buildCascadeDeleteIndices method

Future<Map<int, Set<int>>> buildCascadeDeleteIndices(
  1. String sheetName,
  2. List<String> idsToDelete, {
  3. Set<String>? visited,
})

Constrói de forma recursiva todas as requisições de deleção para os filhos (e netos) caso o onDeleteCascade esteja ativado no ForeignKey. Retorna um Map agrupando por sheetId (GID) um Set de índices de linha únicos a deletar.

Implementation

Future<Map<int, Set<int>>> buildCascadeDeleteIndices(
  String sheetName,
  List<String> idsToDelete, {
  Set<String>? visited,
}) async {
  Map<int, Set<int>> indicesBySheet = {};
  if (idsToDelete.isEmpty) return indicesBySheet;

  visited ??= {};
  if (visited.contains(sheetName)) {
    return indicesBySheet; // Evita loop infinito em dependências circulares
  }
  visited.add(sheetName);

  final dependents =
      foreignKeys?.where(
        (fk) => fk.lookupTable == sheetName && fk.onDeleteCascade,
      ) ??
      [];

  for (final fk in dependents) {
    final childRepo = repo(fk.sourceTable);
    final childData = await childRepo.findAll();

    List<String> childIdsToDelete = [];
    Set<int> childRowIndices = {}; // Utiliza Set para garantir índices únicos

    for (int i = 0; i < childData.length; i++) {
      final row = childData[i];
      final fkValue = row[fk.sourceKeyColumn]?.toString();

      if (fkValue != null && idsToDelete.contains(fkValue)) {
        if (row.containsKey('id') && row['id'].toString().isNotEmpty) {
          childIdsToDelete.add(row['id'].toString());
        }
        childRowIndices.add(i + 1);
      }
    }

    if (childRowIndices.isNotEmpty) {
      final childGid = await childRepo.getGid();
      indicesBySheet.putIfAbsent(childGid, () => {}).addAll(childRowIndices);
    }

    if (childIdsToDelete.isNotEmpty) {
      final cascadeIndices = await buildCascadeDeleteIndices(
        fk.sourceTable,
        childIdsToDelete,
        visited: Set.from(visited), // Passa cópia do Set para a ramificação
      );

      // Faz o merge dos resultados
      cascadeIndices.forEach((gid, indices) {
        indicesBySheet.putIfAbsent(gid, () => {}).addAll(indices);
      });
    }
  }
  return indicesBySheet;
}