Esempio n. 1
0
    def resolver_string(self):
        if not self.is_alias_key:
            return None
        if self.is_range:
            # 子テーブル且つレンジキーの場合はエイリアスキーとなる
            l = len(self.parent.tag_name) + len(TAG_SEPARATOR)
            parent = self.parent.parent_table
            parent_rk_name = parent.range_key.name

            body = IndentString()

            # getter
            body.add('@property')
            body.indent(
                f'def {self.name}(self) -> def_enum.{self.target_enum_name}:')
            body.add(
                f'return self.Meta.key_alias_type.to(int(self.{parent_rk_name}[{l}:]))'
            )
            body.outdent()
            body.blank_line()
            # setter
            body.add(f'@{self.name}.setter')
            body.indent(f'def {self.name}(self, val):')
            body.indent('if val is None:')
            body.add('return')
            body.outdent()
            body.add(
                f'self.{parent_rk_name} = f"{self.parent.tag_name}{TAG_SEPARATOR}{{val.value}}"'
            )
            body.outdent()
            body.outdent()

            return body
        return None
Esempio n. 2
0
    def render_header(self) -> IndentString:
        """
        ヘッダ出力

        :return: IndentString
        """
        # インポートするモジュール群
        d = IndentString()
        l = [
            'from __future__ import annotations',
            'import uuid',
            f'from {self.out_module_name} import masters',
            'from datetime import datetime',
            f'from {self.out_module_name} import def_enum',
            'from hatsudenki.packages import field',
            'from hatsudenki.packages.marked import MarkedObject, Markable, MarkedObjectWithIndex',
            'from hatsudenki.packages.table.index import PrimaryIndex, LSI, GSI',
            'from hatsudenki.packages.table.multi import MultiHatsudenkiTable',
            'from hatsudenki.packages.table.solo import SoloHatsudenkiTable',
            'from hatsudenki.packages.table.child import ChildMultiHatsudenkiTable',
            'from hatsudenki.packages.table.child_solo import ChildSoloHatsudenkiTable',
        ]
        d.add(*l)
        d.blank_line(2)

        d.indent('def table_setup():')
        d.add('from hatsudenki.packages.manager.table import TableManager')
        d.add(
            'print(f"load all tables OK. collections={TableManager.get_collection_num()}  tables={TableManager.get_table_num()}")')
        d.blank_line(2)

        return d
Esempio n. 3
0
    def resolver_string(self):
        """
        リゾルバ

        :return: IndexString
        """
        if not self.is_alias_key:
            # エイリアスキーでなければ不要
            return None

        # エイリアスキーはリゾルバが必要
        l = len(self.parent.tag_name) + len(TAG_SEPARATOR)
        parent = self.parent.parent_table
        body = IndentString()
        # getter
        body.add('@property')
        body.indent(f'def {self.name}(self) -> {self.PythonValueTypeStr}:')
        body.add(f'return {self.PythonValueTypeStr}(self.{parent.range_key.name}[{l}:])')
        body.outdent()

        body.blank_line()

        # setter
        body.add(f'@{self.name}.setter')
        body.indent(f'def {self.name}(self, val: {self.PythonValueTypeStr}):')
        body.indent('if val is None:')
        body.add('return')
        body.outdent()
        body.add(
            f'self.{self.parent.parent_table.range_key.name} = f"{self.parent.tag_name}{TAG_SEPARATOR}{self.resolver_setter_name}"')
        body.outdent()

        return body
Esempio n. 4
0
 def render_header(self):
     u = IndentString()
     u.add('import enum')
     u.add(
         'from hatsudenki.packages.master.model import EnumResolver, MasterResolver'
     )
     u.blank_line(2)
     return u
Esempio n. 5
0
    def render_meta(self):
        """
        Metaクラスの出力

        :return: IndexStringインスタンス
        """
        table = self.data
        # hashキー及びrangeキーを取得
        hk = table.hash_key
        rk = table.range_key

        # 単一か子かによって継承元が変わる
        is_alone = table.is_alone
        if is_alone:
            # 単一テーブルの場合は普通に親から継承
            meta = IndentString('class Meta(SoloHatsudenkiTable.Meta):')
        else:
            # 子テーブルの場合はベースに加え、親テーブルのMetaも継承
            meta = IndentString(f'class Meta(ChildMultiHatsudenkiTable.Meta, {table.parent_table.class_name}.Meta):')

        # 共通属性
        meta.add(f'label = "{table.label}"')
        meta.add(f'is_root = {is_alone}')
        meta.add(f'table_name = "{table.table_name}"')

        # 単一テーブルか否かで処理を分岐
        if is_alone:
            # コレクション名
            meta.add(f'collection_name = "{table.collection_name}"')
            # キー情報
            opt = {
                'hash_key': hk.name
            }
            if rk is not None:
                # rangeキーが存在する場合は追加
                opt['range_key'] = rk.name

            # キャパシティユニット
            cap_unit = table.capacity_units
            opt['read_cap'] = cap_unit['read']
            opt['write_cap'] = cap_unit['write']
            # インデックス
            meta.add(f'primary_index = PrimaryIndex(name=None, {self._render_opt_str(opt)})')
        else:
            # 個別にクラスを出力する必要がある場合
            if rk:
                meta.add(rk.class_string)

            # TAGネーム
            meta.add(f'tag_name = "{table.tag_name}"')
            if rk is not None:
                # aliasキー
                meta.add(f'key_alias_name = "{rk.name}"')
                # aliasキータイプ
                meta.add(f'key_alias_type = {rk.def_python_field_class({})}')
        # 空行
        meta.blank_line()
        return meta
Esempio n. 6
0
 def render_header(self) -> IndentString:
     u = IndentString()
     u.add('from hatsudenki.packages.cache.base import column')
     u.add('from hatsudenki.packages.cache.base.index import PrimaryIndex')
     u.add(
         'from hatsudenki.packages.master.model import MasterModelSolo, MasterModelMulti'
     )
     u.blank_line(2)
     return u
Esempio n. 7
0
    def render(self):
        u = IndentString()

        if self.data.is_out_desc:
            u.add(f'using System.ComponentModel;')
            u.blank_line()

        u.add(f'public enum Enum{self.data.full_classname}')
        u.indent('{')
        for v in self.data.values:
            if self.data.is_out_desc:
                u.add(f'{v.cs_desc}')
            u.add(f'{v.cs_str}')

        u.add(f'MAX = {len(self.data.values)},')
        u.outdent('}')
        return u
Esempio n. 8
0
    def resolver_string(self):
        if not self.is_alias_key:
            return None
        if self.is_range:
            # 子テーブル且つレンジキーの場合はエイリアスキーとなる
            l = len(self.parent.tag_name) + len(TAG_SEPARATOR)
            parent = self.parent.parent_table
            parent_rk_name = parent.range_key.name

            body = IndentString()

            # getter
            body.add('@property')
            body.indent(
                f'def {self.name}(self) -> {self.python_value_type_str}:')
            body.indent(f'if self.{parent_rk_name}:')
            body.add(
                f'd = self.Meta.key_alias_type.get_data(self.{parent_rk_name}[{l}:])'
            )
            body.outdent()
            body.indent('else:')
            body.add('d = self.Meta.key_alias_type.get_data(None)')
            body.outdent()
            body.add('d.parent = self')
            body.add('return d')
            body.outdent()

            body.blank_line()

            # setter
            body.add(f'@{self.name}.setter')
            body.indent(f'def {self.name}(self, val):')
            body.indent('if val is None:')
            body.add('return')
            body.outdent()
            body.indent('if val.is_empty():')
            body.add('return')
            body.outdent()
            body.add(
                f'self.{parent_rk_name} = f"{self.parent.tag_name}{TAG_SEPARATOR}{{val}}"'
            )
            body.outdent()

            return body
        return None
Esempio n. 9
0
    def render(self):
        """
        出力

        :return: IndentString
        """
        table = self.data

        # 継承元の決定
        if table.is_alone:
            # solo or multi
            if table.range_key is not None:
                parent_cls_name = 'MultiHatsudenkiTable'
            else:
                parent_cls_name = 'SoloHatsudenkiTable'
        else:
            # solo or multi
            if table.range_key:
                parent_cls_name = f'{table.parent_table.class_name}, ChildMultiHatsudenkiTable'
            else:
                parent_cls_name = f'{table.parent_table.class_name}, ChildSoloHatsudenkiTable'

        # クラス定義
        cls = IndentString(f'class {table.class_name}({parent_cls_name}):')

        # Metaクラス
        cls.add(self.render_meta())

        cls.blank_line()

        cls.add(self.render_fields())
        cls.blank_line()

        # Index
        cls.add(self.render_index())
        cls.blank_line()
        # init
        cls.add(self.render_init())
        cls.blank_line()
        # resolver
        cls.add(self.render_resolver())

        cls.blank_line()

        return cls
Esempio n. 10
0
    def render(self):
        ToolOutput.anchor(f'{self.data.label} をMarkdownに変換')
        u = IndentString()
        u.add(f'# {self.data.excel_sheet_name}')
        u.add(f'## 情報')
        u.add(self.data.description if self.data.
              description else '*!! descriptionが設定されていません !!*')
        u.blank_line()

        u.add(self._gen_info().render())

        u.add(f'## 担当者')
        u.add(self._gen_assigner().render())

        u.add(f'## スキーマ情報')
        u.add(self._column().render())

        ToolOutput.pop('OK')
        return u
Esempio n. 11
0
    def _enum(self):
        u = IndentString()
        u.indent(f'class Enum{self.data.full_classname}(enum.IntEnum):')
        for v in self.data.values:
            u.add(v.python_str)

        if self.data.is_selector:
            u.blank_line()
            u.add('@classmethod')
            u.indent('def resolve(cls, value: int):')
            u.add('from common import masters')
            for v in self.data.values:
                u.add(v.resolve_name)
            u.outdent()

        # 日本語名を出力します
        u.blank_line()
        u.add('@classmethod')
        u.indent('def reverse(cls, value: int) -> str:')
        for v in self.data.values:
            u.add(
                f'if value == cls.{v.enum_value_name}: return "{v.excel_name}"'
            )
        u.outdent()

        u.blank_line(2)

        return u
Esempio n. 12
0
    def render(self, name):
        hash_key = next((v for k, v in self.attributes.items() if v.is_hash))

        u = IndentString()
        u.indent(f'class {name}(MarkedObjectWithIndex):')
        u.indent('class Meta:')
        u.add(f"hash_key = '{hash_key.name}'")
        u.outdent()
        u.blank_line()
        u.indent('class Field:')
        for k, v in self.attributes.items():
            u.add(v.class_string)
            u.add(v.gen_def_str())

        u.outdent()
        u.blank_line()
        u.indent('def __init__(self, name, parent: Markable, **kwargs):')
        u.add('super().__init__(name, parent)')
        u.add('ft = self.__class__.Field')
        for k, v in self.attributes.items():
            u.add(v.gen_init_str(direct_assign=False))

        u.add('')
        return u
Esempio n. 13
0
    def render(self, name):
        """
        クラス出力

        :param name: フィールド名
        :return: IndentString
        """
        u = IndentString()
        u.indent(f'class {name}(MarkedObject):')
        u.indent('class Field:')
        for k, v in self.attributes.items():
            u.add(v.class_string)
            u.add(v.gen_def_str())

        u.outdent()
        u.blank_line()
        u.indent('def __init__(self, name, parent: Markable, **kwargs):')
        u.add('super().__init__(name, parent)')
        u.add('ft = self.__class__.Field')
        for k, v in self.attributes.items():
            u.add(v.gen_init_str(direct_assign=False))

        u.add('')
        return u
Esempio n. 14
0
    def _model(self):
        u = IndentString()
        m = IndentString()
        f = IndentString()

        if self.data.range_key is not None:
            u.indent(f'class {self.data.class_name}(MasterModelMulti):')
        else:
            u.indent(f'class {self.data.class_name}(MasterModelSolo):')

        m.indent('class Meta:')
        m.add(f"table_name = '{self.data.table_name}'")
        m.add(
            f"primary_index = PrimaryIndex({', '.join([f'{quote(l.python_name)}' for l in self.data.cursor_labels])})"
        )

        f.indent('class Field:')

        i = IndentString()
        i.indent('def __init__(self, **kwargs):')
        i.add('super().__init__(**kwargs)')
        i.add('fields = self.__class__.Field')

        resolver = IndentString()
        no_serial = True
        for k, c in self.data.columns.items():
            f.add(c.python_define_name)
            i.add(c.python_init_name)

            if c.type_name == 'master':
                # master
                resolver.add(c.resolver_name)
                resolver.blank_line()
            elif c.type_name == 'chose':
                # select/choseの解決
                resolver.add(c.resolver_name(self.data.columns[c.selector]))
                resolver.blank_line()
            elif c.is_serial_key:
                # ログ用シリアル
                resolver.add(c.serial_resolver_name)
                no_serial = False
        # シリアルがないテーブルではone_cursorを返却する
        if no_serial:
            resolver.add(MasterColumn.serial_resolver_default())

        m.blank_line()
        u.add(m)
        f.blank_line()
        u.add(f)
        u.add(i)

        if resolver.line_num > 0:
            u.blank_line()
            u.add(resolver)

        u.blank_line()
        return u