from .database import * element_schema = {'type': 'str' , 'optional': True , 'readonly': False} def get_reaction_schema(name: str) -> dict[str, dict[str, Any]]: return { 'ORDER BULK' : element_schema, 'ORDER WALL' : element_schema, 'ORDER TANK' : element_schema, 'GLOBAL BULK' : element_schema, 'GLOBAL WALL' : element_schema, 'LIMITING POTENTIAL' : element_schema, 'ROUGHNESS CORRELATION' : element_schema } def get_reaction(name: str) -> dict[str, Any]: ts = read_all(name, f"select * from reactions") d = {} for e in ts: d[e['key']] = str(e['value']) return d def _set_reaction(name: str, cs: ChangeSet) -> DbChangeSet: raw_old = get_reaction(name) old = {} new = {} new_dict = cs.operations[0] schema = get_reaction_schema(name) for key in schema.keys(): if key in new_dict: old[key] = str(raw_old[key]) new[key] = str(new_dict[key]) redo_cs = g_update_prefix | { 'type' : 'reaction' } redo_sql = '' for key, value in new.items(): if redo_sql != '': redo_sql += '\n' redo_sql += f"update reactions set value = '{value}' where key = '{key}';" redo_cs |= { key: value } undo_cs = g_update_prefix | { 'type' : 'reaction' } undo_sql = '' for key, value in old.items(): if undo_sql != '': undo_sql += '\n' undo_sql += f"update reactions set value = '{value}' where key = '{key}';" undo_cs |= { key: value } return DbChangeSet(redo_sql, undo_sql, [redo_cs], [undo_cs]) def set_reaction(name: str, cs: ChangeSet) -> ChangeSet: return execute_command(name, _set_reaction(name, cs)) def get_pipe_reaction_schema(name: str) -> dict[str, dict[str, Any]]: return { 'pipe' : {'type': 'str' , 'optional': False , 'readonly': True }, 'bulk' : {'type': 'float' , 'optional': True , 'readonly': False}, 'wall' : {'type': 'float' , 'optional': True , 'readonly': False} } def get_pipe_reaction(name: str, pipe: str) -> dict[str, Any]: d = {} d['pipe'] = pipe pr = try_read(name, f"select * from reactions_pipe_bulk where pipe = '{pipe}'") d['bulk'] = float(pr['value']) if pr != None else None pr = try_read(name, f"select * from reactions_pipe_wall where pipe = '{pipe}'") d['wall'] = float(pr['value']) if pr != None else None return d class PipeReaction(object): def __init__(self, input: dict[str, Any]) -> None: self.type = 'pipe_reaction' self.pipe = str(input['pipe']) self.bulk = float(input['bulk']) if 'bulk' in input and input['bulk'] != None else None self.wall = float(input['wall']) if 'wall' in input and input['wall'] != None else None self.f_type = f"'{self.type}'" self.f_pipe = f"'{self.pipe}'" self.f_bulk = self.bulk if self.bulk != None else 'null' self.f_wall = self.wall if self.wall != None else 'null' def as_dict(self) -> dict[str, Any]: return { 'type': self.type, 'pipe': self.pipe, 'bulk': self.bulk, 'wall': self.wall } def _set_pipe_reaction(name: str, cs: ChangeSet) -> DbChangeSet: old = PipeReaction(get_pipe_reaction(name, cs.operations[0]['pipe'])) raw_new = get_pipe_reaction(name, cs.operations[0]['pipe']) new_dict = cs.operations[0] schema = get_pipe_reaction_schema(name) for key, value in schema.items(): if key in new_dict and not value['readonly']: raw_new[key] = new_dict[key] new = PipeReaction(raw_new) redo_sql = f"delete from reactions_pipe_bulk where pipe = {new.f_pipe};\ndelete from reactions_pipe_wall where pipe = {new.f_pipe};" if new.bulk != None: redo_sql += f"\ninsert into reactions_pipe_bulk (pipe, value) values ({new.f_pipe}, {new.f_bulk});" if new.wall != None: redo_sql += f"\ninsert into reactions_pipe_wall (pipe, value) values ({new.f_pipe}, {new.f_wall});" undo_sql = f"delete from reactions_pipe_bulk where pipe = {old.f_pipe};\ndelete from reactions_pipe_wall where pipe = {old.f_pipe};" if old.bulk != None: undo_sql += f"\ninsert into reactions_pipe_bulk (pipe, value) values ({old.f_pipe}, {old.f_bulk});" if old.wall != None: undo_sql += f"\ninsert into reactions_pipe_wall (pipe, value) values ({old.f_pipe}, {old.f_wall});" redo_cs = g_update_prefix | new.as_dict() undo_cs = g_update_prefix | old.as_dict() return DbChangeSet(redo_sql, undo_sql, [redo_cs], [undo_cs]) def set_pipe_reaction(name: str, cs: ChangeSet) -> ChangeSet: return execute_command(name, _set_pipe_reaction(name, cs)) def get_tank_reaction_schema(name: str) -> dict[str, dict[str, Any]]: return { 'tank' : {'type': 'str' , 'optional': False , 'readonly': True }, 'value' : {'type': 'float' , 'optional': True , 'readonly': False} } def get_tank_reaction(name: str, tank: str) -> dict[str, Any]: d = {} d['tank'] = tank pr = try_read(name, f"select * from reactions_tank where tank = '{tank}'") d['value'] = float(pr['value']) if pr != None else None return d class TankReaction(object): def __init__(self, input: dict[str, Any]) -> None: self.type = 'tank_reaction' self.tank = str(input['tank']) self.value = float(input['value']) if 'value' in input and input['value'] != None else None self.f_type = f"'{self.type}'" self.f_tank = f"'{self.tank}'" self.f_value = self.value if self.value != None else 'null' def as_dict(self) -> dict[str, Any]: return { 'type': self.type, 'tank': self.tank, 'value': self.value } def _set_tank_reaction(name: str, cs: ChangeSet) -> DbChangeSet: old = TankReaction(get_tank_reaction(name, cs.operations[0]['tank'])) raw_new = get_tank_reaction(name, cs.operations[0]['tank']) new_dict = cs.operations[0] schema = get_tank_reaction_schema(name) for key, value in schema.items(): if key in new_dict and not value['readonly']: raw_new[key] = new_dict[key] new = TankReaction(raw_new) redo_sql = f"delete from reactions_tank where tank = {new.f_tank};" if new.value != None: redo_sql += f"\ninsert into reactions_tank (tank, value) values ({new.f_tank}, {new.f_value});" undo_sql = f"delete from reactions_tank where tank = {old.f_tank};" if old.value != None: undo_sql += f"\ninsert into reactions_tank (tank, value) values ({old.f_tank}, {old.f_value});" redo_cs = g_update_prefix | new.as_dict() undo_cs = g_update_prefix | old.as_dict() return DbChangeSet(redo_sql, undo_sql, [redo_cs], [undo_cs]) def set_tank_reaction(name: str, cs: ChangeSet) -> ChangeSet: return execute_command(name, _set_tank_reaction(name, cs)) #-------------------------------------------------------------- # [EPA2][EPA3][IN][OUT] # ORDER {BULK/WALL/TANK} value # GLOBAL BULK coeff # GLOBAL WALL coeff # BULK link1 (link2) coeff # WALL link1 (link2) coeff # TANK node1 (node2) coeff # LIMITING POTENTIAL value # ROUGHNESS CORRELATION value #-------------------------------------------------------------- def inp_in_reaction(line: str) -> str: tokens = line.split() token0 = tokens[0].upper() if token0 == 'BULK' or token0 == 'WALL': pipe = tokens[1] key = token0.lower() value = tokens[2] return str(f"insert into reactions_pipe_{key} (pipe, value) values ('{pipe}', {value});") elif token0 == 'TANK': tank = tokens[1] value = tokens[2] return str(f"insert into reactions_tank (tank, value) values ('{tank}', {value});") else: line = line.upper().strip() for key in get_reaction_schema('').keys(): if line.startswith(key): value = line.removeprefix(key).strip() return str(f"update reactions set value = '{value}' where key = '{key}';") return str('') def inp_out_reaction(name: str) -> list[str]: lines = [] objs = read_all(name, f"select * from reactions") for obj in objs: key = obj['key'] value = obj['value'] lines.append(f'{key} {value}') objs = read_all(name, f"select * from reactions_pipe_bulk") for obj in objs: pipe = obj['pipe'] value = obj['value'] lines.append(f'BULK {pipe} {value}') objs = read_all(name, f"select * from reactions_pipe_wall") for obj in objs: pipe = obj['pipe'] value = obj['value'] lines.append(f'WALL {pipe} {value}') objs = read_all(name, f"select * from reactions_tank") for obj in objs: tank = obj['tank'] value = obj['value'] lines.append(f'TANK {tank} {value}') return lines def delete_pipe_reaction_by_pipe(name: str, pipe: str) -> ChangeSet: row1 = try_read(name, f"select * from reactions_pipe_bulk where pipe = '{pipe}'") row2 = try_read(name, f"select * from reactions_pipe_wall where pipe = '{pipe}'") if row1 == None and row2 == None: return ChangeSet() return ChangeSet(g_update_prefix | {'type': 'pipe_reaction', 'pipe': pipe, 'bulk': None, 'wall': None}) def delete_tank_reaction_by_tank(name: str, tank: str) -> ChangeSet: row = try_read(name, f"select * from reactions_tank where tank = '{tank}'") if row == None: return ChangeSet() return ChangeSet(g_update_prefix | {'type': 'tank_reaction', 'tank': tank, 'value': None})