Skip to content

Type Method

namedForeignKey(_:)

Deletion specifier for an explicitly-named constraint known to be a referential constraint.
static func namedForeignKey(_ name: String) -> DatabaseSchema.ConstraintDelete

Discussion

Certain old versions of certain databases (I’m looking at you, MySQL 5.7…) do not support dropping a FOREIGN KEY constraint by name without knowing ahead of time that it is a foreign key. When an unfortunate user runs into this, the options are:

  • Trap the resulting error and retry. This is exceptionally awkward to handle automatically, and can lead to retry loops if multiple deletions are specified in a single operation.

  • Force the user to issue a raw SQL query instead. This is obviously undesirable.

  • Force an upgrade of the underlying database. No one should be using MySQL 5.7 anymore, but Fluent recognizes that this isn’t always under the user’s control.

  • Require the user to specify the deletion with DatabaseSchema.ConstraintDelete.constraint(_:), providing the complete, accurate, and current definition of the foreign key. This is information the user may not even know, and certainly should not be forced to repeat here.

  • Provide a means for the user to specify that a given constraint to be deleted by name is known to be a foreign key. For databases which don’t suffer from this particular syntactical issue (so, almost everything), this is exactly the same as specifying DatabaseSchema.ConstraintDelete.name(_:).

In short, this is the marginal best choice from a list of really bad choices - an ugly, backhanded workaround for MySQL 5.7 users.

Note

A static method is provided rather than a new enum case because adding new cases to a public enum without library evolution enabled (which only the stdlib can do) is a source compatibility break and requires a semver-major version bump. This rule is often ignored, but ignoring it doesn’t make the problem moot.