resolveImplicitManyToManyStorage function

ImplicitManyToManyStorageDefinition? resolveImplicitManyToManyStorage({
  1. required SchemaDocument schema,
  2. required String sourceModelName,
  3. required String relationFieldName,
})

Resolves the join-table storage used by an implicit relation field.

Implementation

ImplicitManyToManyStorageDefinition? resolveImplicitManyToManyStorage({
  required SchemaDocument schema,
  required String sourceModelName,
  required String relationFieldName,
}) {
  final sourceModel = schema.findModel(sourceModelName);
  final sourceField = sourceModel?.findField(relationFieldName);
  if (sourceModel == null || sourceField == null) {
    return null;
  }

  if (!_isImplicitManyToManyRelationField(schema, sourceField)) {
    return null;
  }

  final targetModel = schema.findModel(sourceField.type);
  if (targetModel == null) {
    return null;
  }

  final opposite = _oppositeRelationField(schema, sourceModel, sourceField);
  if (opposite == null || !opposite.isList) {
    return null;
  }

  final sourceKeyFields = _implicitManyToManyKeyFields(sourceModel);
  final targetKeyFields = _implicitManyToManyKeyFields(targetModel);
  final sourceJoinColumns = sourceKeyFields
      .map(
        (keyField) => _implicitManyToManyJoinColumn(
          modelDatabaseName: sourceModel.databaseName,
          relationFieldDatabaseName: sourceField.databaseName,
          keyFieldDatabaseName:
              sourceModel.findField(keyField)?.databaseName ?? keyField,
        ),
      )
      .toList(growable: false);
  final targetJoinColumns = targetKeyFields
      .map(
        (keyField) => _implicitManyToManyJoinColumn(
          modelDatabaseName: targetModel.databaseName,
          relationFieldDatabaseName: opposite.databaseName,
          keyFieldDatabaseName:
              targetModel.findField(keyField)?.databaseName ?? keyField,
        ),
      )
      .toList(growable: false);

  final left = _ImplicitRelationEndpoint(
    model: sourceModel,
    field: sourceField,
  );
  final right = _ImplicitRelationEndpoint(model: targetModel, field: opposite);
  final ordered = [left, right]..sort((a, b) => a.sortKey.compareTo(b.sortKey));

  return ImplicitManyToManyStorageDefinition(
    tableName: _implicitManyToManyTableName(ordered[0], ordered[1]),
    sourceModel: sourceModel,
    sourceField: sourceField,
    sourceKeyFields: List<String>.unmodifiable(sourceKeyFields),
    sourceJoinColumns: List<String>.unmodifiable(sourceJoinColumns),
    targetModel: targetModel,
    targetField: opposite,
    targetKeyFields: List<String>.unmodifiable(targetKeyFields),
    targetJoinColumns: List<String>.unmodifiable(targetJoinColumns),
  );
}