""" .. codeauthor:: Tsuyoshi Hombashi <tsuyoshi.hombashi@gmail.com> """ from textwrap import dedent from typing import TYPE_CHECKING, Optional, Sequence import simplesqlite from simplesqlite import SimpleSQLite from tabledata import TableData from typepy import String from .._common import ResultLogger try: import ujson as json except ImportError: import json # type: ignore if TYPE_CHECKING: from ._base import SourceInfo # noqa class TableCreator: def __init__( self, logger, dst_con: SimpleSQLite, add_pri_key_name: Optional[str], result_logger: ResultLogger, verbosity_level: int, ) -> None: self.__logger = logger self.__dst_con = dst_con self.__add_pri_key_name = add_pri_key_name self.__result_logger = result_logger self.__verbosity_level = verbosity_level def create( self, table_data: TableData, index_list: Sequence[str], source_info: "SourceInfo" ) -> None: con_mem = simplesqlite.connect_memdb() con_mem.create_table_from_tabledata( table_data, primary_key=self.__add_pri_key_name, add_primary_key_column=String(self.__add_pri_key_name).is_type(), ) src_table_name = con_mem.fetch_table_names()[0] dst_table_name = src_table_name if self.__require_rename_table(con_mem, src_table_name): dst_table_name = self.__make_unique_table_name(src_table_name) self.__logger.debug( "rename table from '{}' to '{}'".format(src_table_name, dst_table_name) ) is_create_table = True simplesqlite.copy_table( src_con=con_mem, dst_con=self.__dst_con, src_table_name=src_table_name, dst_table_name=dst_table_name, ) else: is_create_table = not self.__dst_con.has_table(dst_table_name) simplesqlite.append_table( src_con=con_mem, dst_con=self.__dst_con, table_name=dst_table_name ) self.__dst_con.create_index_list(dst_table_name, index_list) self.__result_logger.logging_success( source_info.get_name(self.__verbosity_level), dst_table_name, is_create_table ) def __require_rename_table(self, src_con: SimpleSQLite, src_table_name: str) -> bool: if not self.__dst_con.has_table(src_table_name): return False lhs = self.__dst_con.schema_extractor.fetch_table_schema(src_table_name).as_dict() rhs = src_con.schema_extractor.fetch_table_schema(src_table_name).as_dict() if lhs != rhs: self.__logger.debug( dedent( """\ require rename '{table}' because of src table and dst table has a different schema with the same table name: dst-schema={dst_schema} src-schema={src_schema} """ ).format( table=src_table_name, src_schema=json.dumps(lhs, indent=4, ensure_ascii=False), dst_schema=json.dumps(rhs, indent=4, ensure_ascii=False), ) ) return True return False def __make_unique_table_name(self, table_name_base: str) -> str: exist_table_names = self.__dst_con.fetch_table_names() if table_name_base not in exist_table_names: return table_name_base suffix_id = 1 while True: table_name_candidate = "{:s}_{:d}".format(table_name_base, suffix_id) if table_name_candidate not in exist_table_names: return table_name_candidate suffix_id += 1