diff --git a/README.md b/README.md index 7eb383a..59df655 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![Release][release-image]][releases] [![License][license-image]][license] -[release-image]: https://img.shields.io/badge/release-0.0.19-blue.svg?style=flat +[release-image]: https://img.shields.io/badge/release-0.0.20-blue.svg?style=flat [releases]: https://github.com/bakwc/mysql_ch_replicator/releases [license-image]: https://img.shields.io/badge/license-MIT-blue.svg?style=flat diff --git a/mysql_ch_replicator/config.py b/mysql_ch_replicator/config.py index cbdb53e..563482d 100644 --- a/mysql_ch_replicator/config.py +++ b/mysql_ch_replicator/config.py @@ -4,6 +4,10 @@ from dataclasses import dataclass +def stype(obj): + return type(obj).__name__ + + @dataclass class MysqlSettings: host: str = 'localhost' @@ -11,6 +15,19 @@ class MysqlSettings: user: str = 'root' password: str = '' + def validate(self): + if not isinstance(self.host, str): + raise ValueError(f'mysql host should be string and not {stype(self.host)}') + + if not isinstance(self.port, int): + raise ValueError(f'mysql port should be int and not {stype(self.port)}') + + if not isinstance(self.user, str): + raise ValueError(f'mysql user should be string and not {stype(self.user)}') + + if not isinstance(self.password, str): + raise ValueError(f'mysql password should be string and not {stype(self.password)}') + @dataclass class ClickhouseSettings: @@ -19,12 +36,35 @@ class ClickhouseSettings: user: str = 'root' password: str = '' + def validate(self): + if not isinstance(self.host, str): + raise ValueError(f'clickhouse host should be string and not {stype(self.host)}') + + if not isinstance(self.port, int): + raise ValueError(f'clickhouse port should be int and not {stype(self.port)}') + + if not isinstance(self.user, str): + raise ValueError(f'clickhouse user should be string and not {stype(self.user)}') + + if not isinstance(self.password, str): + raise ValueError(f'clickhouse password should be string and not {stype(self.password)}') + @dataclass class BinlogReplicatorSettings: data_dir: str = 'binlog' records_per_file: int = 100000 + def validate(self): + if not isinstance(self.data_dir, str): + raise ValueError(f'binlog_replicator data_dir should be string and not {stype(self.data_dir)}') + + if not isinstance(self.records_per_file, int): + raise ValueError(f'binlog_replicator records_per_file should be int and not {stype(self.data_dir)}') + + if self.records_per_file <= 0: + raise ValueError('binlog_replicator records_per_file should be positive') + class Settings: @@ -48,6 +88,7 @@ def load(self, settings_file): assert isinstance(self.databases, str) or isinstance(self.databases, list) assert isinstance(self.tables, str) or isinstance(self.tables, list) self.binlog_replicator = BinlogReplicatorSettings(**data['binlog_replicator']) + self.validate() @classmethod def is_pattern_matches(cls, substr, pattern): @@ -67,3 +108,8 @@ def is_database_matches(self, db_name): def is_table_matches(self, table_name): return self.is_pattern_matches(table_name, self.tables) + + def validate(self): + self.mysql.validate() + self.clickhouse.validate() + self.binlog_replicator.validate() diff --git a/pyproject.toml b/pyproject.toml index f778ca7..50a6810 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mysql-ch-replicator" -version = "0.0.19" +version = "0.0.20" description = "Tool for replication of MySQL databases to ClickHouse" authors = ["Filipp Ozinov "] license = "MIT"