buildCascadeDeleteIndices method
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 rawRows = await childRepo.getRawRows();
if (rawRows.isEmpty) continue;
final headers = List<String>.from(rawRows[0]);
int fkColIndex = headers.indexOf(fk.sourceKeyColumn);
int idColIndex = headers.indexOf('id');
if (fkColIndex == -1) continue;
List<String> childIdsToDelete = [];
Set<int> childRowIndices = {};
for (int i = 1; i < rawRows.length; i++) {
final row = rawRows[i];
if (row.length <= fkColIndex) continue;
final fkValue = row[fkColIndex]?.toString();
if (fkValue != null && idsToDelete.contains(fkValue)) {
if (idColIndex != -1 && row.length > idColIndex) {
final idVal = row[idColIndex]?.toString();
if (idVal != null && idVal.isNotEmpty) {
childIdsToDelete.add(idVal);
}
}
childRowIndices.add(i);
}
}
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;
}