| 38 | |
| 39 | |
| 40 | class ServerInfo: |
| 41 | def __init__(self, species: ServerSpecies | None, version_str: str) -> None: |
| 42 | self.species = species |
| 43 | self.version_str = version_str |
| 44 | self.version = self.calc_mysql_version_value(version_str) |
| 45 | |
| 46 | @staticmethod |
| 47 | def calc_mysql_version_value(version_str: str) -> int: |
| 48 | if not version_str or not isinstance(version_str, str): |
| 49 | return 0 |
| 50 | try: |
| 51 | major, minor, patch = version_str.split(".") |
| 52 | except ValueError: |
| 53 | return 0 |
| 54 | else: |
| 55 | return int(major) * 10_000 + int(minor) * 100 + int(patch) |
| 56 | |
| 57 | @classmethod |
| 58 | def from_version_string(cls, version_string: str) -> ServerInfo: |
| 59 | if not version_string: |
| 60 | return cls(ServerSpecies.MySQL, "") |
| 61 | |
| 62 | re_species = ( |
| 63 | (r"(?P<version>[0-9\.]+)-MariaDB", ServerSpecies.MariaDB), |
| 64 | (r"[0-9\.]*-TiDB-v(?P<version>[0-9\.]+)-?(?P<comment>[a-z0-9\-]*)", ServerSpecies.TiDB), |
| 65 | (r"(?P<version>[0-9\.]+)[a-z0-9]*-(?P<comment>[0-9]+$)", ServerSpecies.Percona), |
| 66 | # Also matches plain "X.Y.Z" with no suffix (e.g. Homebrew MySQL). |
| 67 | (r"(?P<version>[0-9]+\.[0-9]+\.[0-9]+)[a-z0-9]*(-(?P<comment>[A-Za-z0-9_]+))?", ServerSpecies.MySQL), |
| 68 | ) |
| 69 | for regexp, species in re_species: |
| 70 | match = re.search(regexp, version_string) |
| 71 | if match is not None: |
| 72 | parsed_version = match.group("version") |
| 73 | detected_species = species |
| 74 | break |
| 75 | else: |
| 76 | detected_species = ServerSpecies.MySQL |
| 77 | parsed_version = "" |
| 78 | |
| 79 | return cls(detected_species, parsed_version) |
| 80 | |
| 81 | def __str__(self) -> str: |
| 82 | if self.species: |
| 83 | return f"{self.species.value} {self.version_str}" |
| 84 | else: |
| 85 | return self.version_str |
| 86 | |
| 87 | |
| 88 | class SQLExecute: |