doDeleteSQL method

  1. @override
FutureOr<Iterable<Map<String, dynamic>>> doDeleteSQL(
  1. String entityName,
  2. String table,
  3. SQL sql,
  4. Transaction transaction,
  5. DBSQLMemoryAdapterContext connection,
)
override

Implementation

@override
FutureOr<Iterable<Map<String, dynamic>>> doDeleteSQL(
  String entityName,
  String table,
  SQL sql,
  Transaction transaction,
  DBSQLMemoryAdapterContext connection,
) {
  if (sql.isDummy) return <Map<String, dynamic>>[];

  var map = _getTableMap(table, false);
  if (map == null) {
    return <Map<String, dynamic>>[];
  }

  var tableScheme = getTableScheme(table, relationship: sql.relationship);

  var entityHandler = getEntityHandler(tableName: table);

  final noReferences =
      tableScheme == null || tableScheme.fieldsReferencedTablesLength == 0;

  // A delete by ID needs neither a scan nor resolving every row (below):
  // only the deleted row. A miss falls back to the scan, as in a select.
  var byID = _entryByConditionID(map, sql);
  if (byID != null) {
    var entries = [
      noReferences
          ? byID
          : MapEntry(
              byID.key,
              _resolveEntityMap(byID.value, entityHandler, tableScheme),
            ),
    ];

    _checkNotReferencedEntities(entries, table, sql);

    return _removeEntries(table, entries, map);
  }

  // A relationship delete (e.g. the roles a user no longer has) only needs
  // the rows of its `field == id`; the whole condition is still matched.
  Iterable<MapEntry<Object, Map<String, dynamic>>> candidates = map.entries;
  if (sql.relationship != null) {
    var byIndex = _relationshipEntriesByIndex(
      table,
      map,
      sql.condition,
      narrowAND: true,
    );
    if (byIndex != null) candidates = byIndex;
  }

  if (noReferences) {
    var entries = candidates.where((e) {
      return sql.condition!.matchesEntityMap(
        e.value,
        namedParameters: sql.parametersByPlaceholder,
        entityHandler: entityHandler,
      );
    }).toList();

    _checkNotReferencedEntities(entries, table, sql);

    return _removeEntries(table, entries, map);
  }

  var entries = candidates
      .map((e) {
        var obj = _resolveEntityMap(e.value, entityHandler, tableScheme);

        var match = sql.condition!.matchesEntityMap(
          obj,
          namedParameters: sql.parametersByPlaceholder,
          entityHandler: entityHandler,
        );

        return match ? MapEntry(e.key, obj) : null;
      })
      .nonNulls
      .toList(growable: false);

  _checkNotReferencedEntities(entries, table, sql);

  return _removeEntries(table, entries, map);
}