bestOrder method

void bestOrder()

Sorts the SQLs in the best execution order, to avoid reference issues.

Implementation

void bestOrder() {
  sortByName();

  final entriesReferences = _entriesReferences();
  final entriesRelationships = _entriesRelationships();

  var withParents =
      whereType<TableSQL>().where((e) => e.parentTable != null).toList();
  removeAll(withParents);

  var withRelationship = whereType<CreateTableSQL>()
      .where((e) => e.relationshipsTables.isNotEmpty)
      .toList();
  removeAll(withRelationship);

  var withReference = where((e) {
    var referenceTables = e.referenceTables;
    return referenceTables != null && referenceTables.isNotEmpty;
  }).toList();
  removeAll(withReference);

  withParents._bestOrderLoop(
      entriesReferences: entriesReferences,
      entriesRelationships: entriesRelationships);

  withReference._bestOrderLoop(
      entriesReferences: entriesReferences,
      entriesRelationships: entriesRelationships);

  withRelationship._bestOrderLoop(
      entriesReferences: entriesReferences,
      entriesRelationships: entriesRelationships);

  _bestOrderLoop();

  refsGetter(SQLBuilder e) => e is CreateTableSQL
      ? e.referenceAndRelationshipTables
      : e.referenceTables ?? [];

  _addByRefPos(withReference, addAtEnd: true);
  _addByRefPos(withRelationship, addAtEnd: true, refsGetter: refsGetter);

  while (withReference.isNotEmpty || withRelationship.isNotEmpty) {
    var addRefs = _addByRefPos(withReference);
    _sortByRefsSimple();

    var addRels = _addByRefPos(withRelationship, refsGetter: refsGetter);

    _sortByRels();
    _sortByRefs();
    _bestOrderLoop();

    if (addRefs == 0 && addRels == 0) {
      if (withReference.isNotEmpty) {
        addAll(withReference);
        withReference.clear();
        _bestOrderLoop();
      } else if (withRelationship.isNotEmpty) {
        addAll(withRelationship);
        withRelationship.clear();
        _bestOrderLoop();
      } else {
        break;
      }
    }
  }

  for (var e in withParents.reversed) {
    var idx = _indexOfTable(e.table, 0) ?? 0;
    insert(idx, e);
  }

  withParents.clear();

  var ok = _bestOrderLoop(
      entriesReferences: entriesReferences,
      entriesRelationships: entriesRelationships);

  if (!ok) {
    _log.info(
        "`SQLBuilder.bestOrder`: sort loop detected: ${map((e) => e.mainTable).toList()}");
  }
}