1from __future__ import annotations
2
3from typing import TYPE_CHECKING
4
5from plain.models.backends.base.validation import BaseDatabaseValidation
6from plain.preflight import PreflightResult
7
8if TYPE_CHECKING:
9 from plain.models.fields import Field
10
11
12class DatabaseValidation(BaseDatabaseValidation):
13 def preflight(self) -> list[PreflightResult]:
14 issues = super().preflight()
15 issues.extend(self._check_sql_mode())
16 return issues
17
18 def _check_sql_mode(self) -> list[PreflightResult]:
19 if not (
20 self.connection.sql_mode & {"STRICT_TRANS_TABLES", "STRICT_ALL_TABLES"}
21 ):
22 return [
23 PreflightResult(
24 fix=f"{self.connection.display_name} Strict Mode is not set for the database connection. "
25 f"{self.connection.display_name}'s Strict Mode fixes many data integrity problems in "
26 f"{self.connection.display_name}, such as data truncation upon insertion, by "
27 "escalating warnings into errors. It is strongly "
28 "recommended you activate it.",
29 id="mysql.strict_mode_not_enabled",
30 warning=True,
31 )
32 ]
33 return []
34
35 def check_field_type(self, field: Field, field_type: str) -> list[PreflightResult]:
36 """
37 MySQL has the following field length restriction:
38 No character (varchar) fields can have a length exceeding 255
39 characters if they have a unique index on them.
40 MySQL doesn't support a database index on some data types.
41 """
42 errors = []
43 if (
44 field_type.startswith("varchar")
45 and field.primary_key
46 and (field.max_length is None or int(field.max_length) > 255)
47 ):
48 errors.append(
49 PreflightResult(
50 fix=f"{self.connection.display_name} may not allow unique CharFields to have a max_length "
51 "> 255.",
52 obj=field,
53 id="mysql.unique_charfield_max_length_too_long",
54 warning=True,
55 )
56 )
57
58 return errors