Plain is headed towards 1.0! Subscribe for development updates →

 1from __future__ import annotations
 2
 3from typing import TYPE_CHECKING, Any
 4
 5if TYPE_CHECKING:
 6    from plain.models.backends.base.base import BaseDatabaseWrapper
 7    from plain.models.fields import Field
 8
 9
10class BaseDatabaseValidation:
11    """Encapsulate backend-specific validation."""
12
13    def __init__(self, connection: BaseDatabaseWrapper) -> None:
14        self.connection = connection
15
16    def preflight(self) -> list[Any]:
17        return []
18
19    def check_field_type(self, field: Field, field_type: str) -> list[Any]:
20        """
21        Backend-specific field type validation.
22        Subclasses may override this method to perform validation specific to their database.
23        """
24        return []
25
26    def check_field(self, field: Field, **kwargs: Any) -> list[Any]:
27        errors = []
28        # Backends may implement a check_field_type() method.
29        if (
30            hasattr(self, "check_field_type")
31            and
32            # Ignore any related fields.
33            not getattr(field, "remote_field", None)
34        ):
35            # Ignore fields with unsupported features.
36            db_supports_all_required_features = all(
37                getattr(self.connection.features, feature, False)
38                for feature in field.model.model_options.required_db_features
39            )
40            if db_supports_all_required_features:
41                field_type = field.db_type(self.connection)
42                # Ignore non-concrete fields.
43                if field_type is not None:
44                    errors.extend(self.check_field_type(field, field_type))
45        return errors