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
def class_string(self): u = IndentString( f'class {snake_to_camel(self.name)}Field(field.MasterKeysField):') u.indent('class Value(field.MasterKeysField.Value):') acce = IndentString() excep = IndentString() opt_strings = [] con_body = IndentString() for idx, t in enumerate(self.targets): acce.add('@property') acce.indent(f'def t{idx}(self):') c = self.get_target_table_class_name(idx) if self.is_enum(t): acce.add( f'return {c}(int(self.label_list[{idx}])) if self.label_list[{idx}] else None' ) else: acce.add(f'return self.label_list[{idx}]') acce.outdent('') if self.is_master(t): acce.indent(f'def resolved_t{idx}(self):') acce.add(f'return {c}.get_by_cursor(self.t{idx})') acce.outdent('') elif self.is_enum(t): # enumにリゾルバは存在しない pass else: acce.indent(f'async def resolved_t{idx}(self):') acce.add(f'return await {c}.query_by_cursor(self.t{idx})') acce.outdent('') excep.indent(f'if not isinstance(t{idx}, {c}):') excep.add( f'raise Exception(f"not [{c}] given {{type(t{idx}).__name__}}")' ) excep.outdent() opt_strings.append(f't{idx}: {c}') if self.is_enum(t): con_body.add(f'self.label_list[{idx}] = str(t{idx}.value)') else: con_body.add(f'self.label_list[{idx}] = t{idx}.one_cursor') if not self.parent.is_alone: con_body.add('self.update_key()') con_head = IndentString( f'def connect(self, {", ".join(opt_strings)}):') con_head.add(excep) con_head.add(con_body) u.add(acce, con_head) return u
def serial_resolver_default(): i = IndentString() i.add('@property') i.indent('def log_id(self):') i.add('return self.one_cursor') return i
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
def cs_access_name(self): u = IndentString() t = self.get_target_table() u.add(f'public {t.class_name} {self.cs_name}Table()') u.indent('{') u.add(f'return {t.class_name}.Instance;') u.outdent('}') return u
def _store(self): u = IndentString() u.add('[MessagePackObject]') u.add(f'public class {self.record_type}s') u.indent('{') u.add('[Key(0)]') u.add(f'public {self.record_type}[] Array;') u.outdent('}') return u
def resolver_name(self, selector: ColumnSelect): u = IndentString() te = selector.resolve_relation() u.add('@property') u.indent(f'def resolved_{self.python_name}(self):') u.add('from common.enums import def_enum') u.add(f'tbl = def_enum.Enum{te.full_classname}.resolve(self.{selector.python_name})') u.add(f'return tbl.get(self.{self.python_name})') return u
def _get_list(self): hk = self.data.hash_key rk = self.data.range_key if rk is None: return None u = IndentString() n = f'{hk.cs_type_name} {hk.column_name}' u.add(f'public List<{self.record_type}> GetList({n})') u.indent('{') u.add(f'return _records[{hk.column_name}];') u.outdent('}') return u
def serial_resolver_name(self): if not self.is_serial_key: return None serial = f"'{self.table_name}_'" + f' + str(self.{self.column_name}).zfill(10)' i = IndentString() i.add('@property') i.indent('def log_id(self):') i.add(f'return {serial}') return i
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
def _get(self): u = IndentString() hk = self.data.hash_key rk = self.data.range_key if rk: n = f'{hk.cs_type_name} {hk.column_name}, {rk.cs_type_name} {rk.column_name}' c = f'return _records[{hk.column_name}].Find(x => x.GetRangeKey() == {rk.column_name});' else: n = f'{hk.cs_type_name} {hk.column_name}' c = f'return _records[{hk.column_name}];' u.add(f'public {self.record_type} Get({n})') u.indent('{') u.add(f'{c}') u.outdent('}') return u
def _find(self, is_all: bool): if self.data.range_key is None: return None u = IndentString() hk = self.data.hash_key if is_all: t = f'List<{self.record_type}>' n = 'FindAll' else: t = self.record_type n = 'Find' u.add( f'public {t} {n}({hk.cs_type_name} {hk.column_name}, Predicate<{self.record_type}> func)' ) u.indent('{') u.add(f'return _records[{hk.column_name}].{n}(func);') u.outdent('}') return u
def _records(self): u = IndentString() hk = self.data.hash_key rk = self.data.range_key # レコード本体 if rk: t = f'Dictionary<{hk.cs_type_name}, List<{self.record_type}>>' else: t = f'Dictionary<{hk.cs_type_name}, {self.record_type}>' u.add(f'private {t} _records = new {t}();') u.add(f'public {t} Records') u.indent('{') u.add('get') u.indent('{') u.add('return _records;') u.outdent('}') u.outdent('}') return u
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
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
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
def _repository(self): u = IndentString() u.add(f'public class {self.data.class_name}') u.indent('{') u.add(f'public const string TableName = "{self.data.table_name}";') # シングルトン実装 u.add(self._singleton()) # コンストラクタ u.add(f'private {self.data.class_name}() {{ }}') # レコード本体 u.add(self._records()) # 一件取得 u.add(self._get()) u.add(self._get_list()) # find u.add(self._find(is_all=False)) u.add(self._find(is_all=True)) # filter u.add(self._filter(is_all=False)) u.add(self._filter(is_all=True)) # loader u.add(self._load()) u.add(f'public void Release()') u.indent('{') u.add('_records.Clear();') u.add('_records = null;') u.add('_instance = null;') u.outdent('}') u.outdent('}') return u
def _model(self): u = IndentString() u.add('[MessagePackObject]') u.add(f'public class {self.record_type}') u.indent('{') keys = [c for c in self.data.columns.values() if not c.is_no_pack] keys.extend( [c for c in self.data.shadow_columns.values() if not c.is_no_pack]) args = ', '.join((c.cs_argument_name for c in keys)) u.add(f'public {self.record_type}({args})') u.indent('{') [u.add(c.cs_assign_name) for c in keys] u.outdent('}') for idx, c in enumerate(keys): if c.is_no_pack: continue u.add(f'[Key({idx})]', c.cs_define_name) hk = self.data.hash_key u.add(f'public {hk.cs_type_name} GetHashKey()') u.indent('{') u.add(f'return {hk.cs_name};') u.outdent('}') rk = self.data.range_key if rk: u.add(f'public {rk.cs_type_name} GetRangeKey()') u.indent('{') u.add(f'return {rk.cs_name};') u.outdent('}') for c in keys: if not c.is_no_pack: u.add(c.cs_access_name()) u.outdent('}') return u
def resolver_name(self): u = IndentString() u.add('@property') u.indent(f'def resolved_{self.python_name}(self):') t = self.get_target_table() if t.range_key is None: u.add(f'a = {self.get_target_table().class_name}.get(self.{self.python_name})') u.indent('if a is None:') u.add('return None') u.outdent() u.indent('if a.is_nothing:') u.add('return None') u.outdent() u.add('return a') else: u.add(f'a = {self.get_target_table().class_name}.find(self.{self.python_name})') u.indent('if len(a) > 0 and a[0].is_nothing:') u.add('return None') u.outdent() u.add('return a') return u
def _singleton(self): u = IndentString() # シングルトン実装 u.add(f'private static {self.data.class_name} _instance;') u.add(f'public static {self.data.class_name} Instance') u.indent('{') u.add('get') u.indent('{') u.add('if (_instance == null)') u.indent('{') u.add(f'_instance = new {self.data.class_name}();') u.outdent('}') u.add('return _instance;') u.outdent('}') u.outdent('}') return u
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
def _load(self): hk = self.data.hash_key u = IndentString() u.add(f'public void FinishedLoad({self.record_type}s records)') u.indent('{') u.add('_records.Clear();') u.add(f'foreach({self.record_type} rec in records.Array)') u.indent('{') u.add(f'{hk.cs_type_name} hk = rec.GetHashKey();') if self.data.range_key is None: u.add('_records.Add(hk, rec);') else: u.add('if(!_records.ContainsKey(hk))') u.indent('{') u.add(f'_records.Add(hk, new List<{self.record_type}>());') u.outdent('}') u.add('_records[hk].Add(rec);') u.outdent('}') u.outdent('}') return u
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
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
def _filter(self, is_all: bool): u = IndentString() hk = self.data.hash_key if is_all: t = f'List<{self.record_type}>' n = 'FilterAll' fn = 'FindAll' else: t = self.record_type n = 'Filter' fn = 'Find' u.add(f'public {t} {n}(Predicate<{self.record_type}> func)') u.indent('{') if is_all: u.add( f'List<{self.record_type}> ret = new List<{self.record_type}>();' ) if self.data.range_key is None: u.add( f'foreach(KeyValuePair<{hk.cs_type_name}, {self.record_type}> l in _records)' ) else: u.add( f'foreach(KeyValuePair<{hk.cs_type_name}, List<{self.record_type}>> l in _records)' ) u.indent('{') if is_all: if self.data.range_key is None: u.add(f'{self.record_type} v = l.Value;') u.add('if(func(v))') u.indent('{') u.add('ret.Add(v);') u.outdent('}') u.outdent('}') u.add('return ret;') else: u.add(f'List<{self.record_type}> v = l.Value;') u.add(f'List<{self.record_type}> t = v.FindAll(func);') u.add('if(t.Count > 0)') u.indent('{') u.add('ret.AddRange(t);') u.outdent('}') u.outdent('}') u.add('return ret;') else: if self.data.range_key is None: u.add(f'{self.record_type} v = l.Value;') u.add('if(func(v))') u.indent('{') u.add('return v;') u.outdent('}') u.outdent('}') u.add('return null;') else: u.add(f'List<{self.record_type}> v = l.Value;') u.add(f'{self.record_type} t = v.Find(func);') u.add('if( t != null )') u.indent('{') u.add('return t;') u.outdent('}') u.outdent('}') u.add('return null;') u.outdent('}') return u