findFieldsReferencedTablesImpl method

  1. @override
FutureOr<Map<String, TableFieldReference>> findFieldsReferencedTablesImpl(
  1. DBSQLiteConnectionWrapper connection,
  2. String table
)
override

Finds the foreign keys of table, with connection: the referenced table (and field) of each referencing field, by the field name.

Implemented by the adapters that introspect their schema (see listTablesNamesImpl). Default: throws UnsupportedError.

Implementation

@override
FutureOr<Map<String, TableFieldReference>> findFieldsReferencedTablesImpl(
  DBSQLiteConnectionWrapper connection,
  String table,
) {
  var results = connection.select(
    'SELECT * FROM pragma_foreign_key_list(?)',
    [table],
  );

  var mapEntriesRet = results
      .map<FutureOr<MapEntry<String, TableFieldReference>?>>((r) {
        var sourceField = r['from']?.toString();
        var targetTable = r['table']?.toString();
        var targetField = r['to']?.toString();

        if (sourceField == null || targetTable == null) {
          return null as FutureOr<MapEntry<String, TableFieldReference>?>;
        }

        // `PRAGMA foreign_key_list` reports a `null` target column when
        // the reference points at the target's PRIMARY KEY implicitly.
        FutureOr<String?> targetFieldRet =
            targetField ??
            getTableScheme(targetTable).resolveMapped((s) => s?.idFieldName);

        return targetFieldRet.resolveMapped<
          MapEntry<String, TableFieldReference>?
        >((targetField) {
          if (targetField == null) return null;

          var sourceFieldsTypesRet = getTableFieldsTypes(table);
          var targetFieldsTypesRet = getTableFieldsTypes(targetTable);

          return sourceFieldsTypesRet.resolveBoth(targetFieldsTypesRet, (
            sourceFieldsTypes,
            targetFieldsTypes,
          ) {
            var sourceFieldType = sourceFieldsTypes?[sourceField] ?? String;
            var targetFieldType = targetFieldsTypes?[targetField] ?? String;

            return MapEntry<String, TableFieldReference>(
              sourceField,
              TableFieldReference(
                table,
                sourceField,
                sourceFieldType,
                targetTable,
                targetField,
                targetFieldType,
              ),
            );
          });
        });
      })
      .toList()
      .resolveAll();

  return mapEntriesRet.resolveMapped(
    (mapEntries) =>
        Map<String, TableFieldReference>.fromEntries(mapEntries.nonNulls),
  );
}