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