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(self, field: Field, **kwargs: Any) -> list[Any]:
20 errors = []
21 # Backends may implement a check_field_type() method.
22 if (
23 hasattr(self, "check_field_type")
24 and
25 # Ignore any related fields.
26 not getattr(field, "remote_field", None)
27 ):
28 # Ignore fields with unsupported features.
29 db_supports_all_required_features = all(
30 getattr(self.connection.features, feature, False)
31 for feature in field.model.model_options.required_db_features
32 )
33 if db_supports_all_required_features:
34 field_type = field.db_type(self.connection)
35 # Ignore non-concrete fields.
36 if field_type is not None:
37 errors.extend(self.check_field_type(field, field_type))
38 return errors