Accept Merge Request #81: (api -> master)
Merge Request: Add essential parser Created By: @王琼钰 Accepted By: @王琼钰 URL: https://tjwater.coding.net/p/tjwatercloud/d/TJWaterServer/git/merge/81
This commit is contained in:
@@ -2,7 +2,7 @@ from .project import list_project, have_project, create_project, delete_project
|
||||
from .project import is_project_open, get_project_open_count, open_project, close_project
|
||||
from .project import copy_project
|
||||
|
||||
from .parser import read_inp
|
||||
from .api_parser import read_inp
|
||||
|
||||
from .operation import API_ADD, API_UPDATE, API_DELETE
|
||||
from .operation import ChangeSet
|
||||
|
||||
@@ -7,13 +7,66 @@ from .s4_tanks import *
|
||||
from .s5_pipes import *
|
||||
from .s6_pumps import *
|
||||
from .s7_valves import *
|
||||
from .s8_tags import *
|
||||
from .s9_demands import *
|
||||
from .s10_status import *
|
||||
from .s11_patterns import *
|
||||
from .s12_curves import *
|
||||
from .s13_controls import *
|
||||
from .s14_rules import *
|
||||
from .s15_energy import *
|
||||
from .s16_emitters import *
|
||||
from .s17_quality import *
|
||||
from .s18_sources import *
|
||||
from .s19_reactions import *
|
||||
from .s20_mixing import *
|
||||
from .s21_times import *
|
||||
from .s22_report import *
|
||||
from .s23_options import *
|
||||
from .s24_coordinates import *
|
||||
from .s25_vertices import *
|
||||
from .s26_labels import *
|
||||
from .s27_backdrop import *
|
||||
from .s28_end import *
|
||||
|
||||
|
||||
|
||||
def parse_inp(inp: str) -> dict[str, list[str]]:
|
||||
section_name = ['TITLE', 'JUNCTIONS', 'RESERVOIRS', 'TANKS', 'PIPES',
|
||||
'PUMPS', 'VALVES', 'TAGS', 'DEMANDS', 'STATUS',
|
||||
'PATTERNS', 'CURVES', 'CONTROLS', 'RULES', 'ENERGY',
|
||||
'EMITTERS', 'QUALITY', 'SOURCES', 'REACTIONS', 'MIXING',
|
||||
'TIMES', 'REPORT', 'OPTIONS', 'COORDINATES', 'VERTICES',
|
||||
'LABELS', 'BACKDROP', 'END']
|
||||
|
||||
file: dict[str, list[str]] = {}
|
||||
for s in section_name:
|
||||
file[s] = []
|
||||
|
||||
section = ''
|
||||
|
||||
for line in open(inp):
|
||||
line = line.strip()
|
||||
if line == '':
|
||||
section = ''
|
||||
continue
|
||||
|
||||
if line.startswith('['):
|
||||
is_section = False
|
||||
for s in section_name:
|
||||
if line.startswith(f'[{s}'):
|
||||
section = s
|
||||
is_section = True
|
||||
break
|
||||
if is_section:
|
||||
continue
|
||||
|
||||
if section != '':
|
||||
file[section].append(line)
|
||||
|
||||
return file
|
||||
|
||||
|
||||
|
||||
|
||||
def read_inp(name: str, inp: str):
|
||||
@@ -28,25 +81,27 @@ def read_inp(name: str, inp: str):
|
||||
|
||||
section = ''
|
||||
|
||||
title : str = ''
|
||||
junctions : dict[str, dict[str, Any]] = {}
|
||||
reservoirs : dict[str, dict[str, Any]] = {}
|
||||
tanks : dict[str, dict[str, Any]] = {}
|
||||
pipes : dict[str, dict[str, Any]] = {}
|
||||
pumps : dict[str, dict[str, Any]] = {}
|
||||
valves : dict[str, dict[str, Any]] = {}
|
||||
demands : dict[str, list[dict[str, Any]]] = {}
|
||||
status : dict[str, dict[str, Any]] = {}
|
||||
patterns : dict[str, list[float]] = {}
|
||||
curves : dict[str, list[dict[str, float]]] = {}
|
||||
emitters : dict[str, float] = {}
|
||||
times : dict[str, str] = {}
|
||||
options : dict[str, str] = {}
|
||||
file: dict[str, list[str]] = {}
|
||||
|
||||
_1_title : str = ''
|
||||
_2_junctions : dict[str, dict[str, Any]] = {}
|
||||
_3_reservoirs : dict[str, dict[str, Any]] = {}
|
||||
_4_tanks : dict[str, dict[str, Any]] = {}
|
||||
_5_pipes : dict[str, dict[str, Any]] = {}
|
||||
_6_pumps : dict[str, dict[str, Any]] = {}
|
||||
_7_valves : dict[str, dict[str, Any]] = {}
|
||||
_9_demands : dict[str, list[dict[str, Any]]] = {}
|
||||
_10_status : dict[str, dict[str, Any]] = {}
|
||||
_11_patterns : dict[str, list[float]] = {}
|
||||
_12_curves : dict[str, list[dict[str, float]]] = {}
|
||||
_16_emitters : dict[str, float] = {}
|
||||
_21_times : dict[str, str] = {}
|
||||
_22_options : dict[str, str] = {}
|
||||
|
||||
for line in open(inp):
|
||||
line = line.strip()
|
||||
|
||||
if line.startswith(';'):
|
||||
if line.startswith(';') and not line.endswith(':'):
|
||||
continue
|
||||
if line.endswith(';'):
|
||||
line = line.removesuffix(';')
|
||||
@@ -110,111 +165,111 @@ def read_inp(name: str, inp: str):
|
||||
continue
|
||||
|
||||
if section == 'title':
|
||||
if title == '':
|
||||
title += '\n'
|
||||
title += line
|
||||
if _1_title == '':
|
||||
_1_title += '\n'
|
||||
_1_title += line
|
||||
continue
|
||||
elif section == JUNCTION:
|
||||
junction_demand = float(tokens[2]) if tokens_len >= 3 else None
|
||||
junction_pattern = tokens[3] if tokens_len == 4 else None
|
||||
junctions[tokens[0]] = {'id': tokens[0], 'elevation': tokens[1], 'demand': junction_demand, 'pattern': junction_pattern}
|
||||
_2_junctions[tokens[0]] = {'id': tokens[0], 'elevation': tokens[1], 'demand': junction_demand, 'pattern': junction_pattern}
|
||||
continue
|
||||
elif section == RESERVOIR:
|
||||
reservoir_pattern = tokens[2] if tokens_len == 3 else None
|
||||
reservoirs[tokens[0]] = {'id': tokens[0], 'head': tokens[1], 'pattern': reservoir_pattern}
|
||||
_3_reservoirs[tokens[0]] = {'id': tokens[0], 'head': tokens[1], 'pattern': reservoir_pattern}
|
||||
continue
|
||||
elif section == TANK:
|
||||
tank_vol_curve = tokens[7] if tokens_len >= 8 else None
|
||||
tank_overflow = tokens[8].upper() if tokens_len == 9 else None
|
||||
tanks[tokens[0]] = {'id': tokens[0], 'elevation': tokens[1], 'init_level': tokens[2], 'min_level': tokens[3], 'max_level': tokens[4], 'diameter': tokens[5], 'min_vol': tokens[6], 'vol_curve': tank_vol_curve, 'overflow': tank_overflow}
|
||||
_4_tanks[tokens[0]] = {'id': tokens[0], 'elevation': tokens[1], 'init_level': tokens[2], 'min_level': tokens[3], 'max_level': tokens[4], 'diameter': tokens[5], 'min_vol': tokens[6], 'vol_curve': tank_vol_curve, 'overflow': tank_overflow}
|
||||
continue
|
||||
elif section == PIPE:
|
||||
# status is must-have, here fix input
|
||||
pipe_status = tokens[7].upper() if tokens_len == 8 else PIPE_STATUS_OPEN
|
||||
pipes[tokens[0]] = {'id': tokens[0], 'node1': tokens[1], 'node2': tokens[2], 'length': tokens[3], 'diameter': tokens[4], 'roughness': tokens[5], 'minor_loss': tokens[6], 'status': pipe_status}
|
||||
_5_pipes[tokens[0]] = {'id': tokens[0], 'node1': tokens[1], 'node2': tokens[2], 'length': tokens[3], 'diameter': tokens[4], 'roughness': tokens[5], 'minor_loss': tokens[6], 'status': pipe_status}
|
||||
continue
|
||||
elif section == PUMP:
|
||||
pumps[tokens[0]] = {'id': tokens[0], 'node1': tokens[1], 'node2': tokens[2]}
|
||||
_6_pumps[tokens[0]] = {'id': tokens[0], 'node1': tokens[1], 'node2': tokens[2]}
|
||||
for i in range(3, tokens_len, 2):
|
||||
pumps[tokens[0]] |= { tokens[i].lower(): tokens[i + 1] }
|
||||
_6_pumps[tokens[0]] |= { tokens[i].lower(): tokens[i + 1] }
|
||||
continue
|
||||
elif section == VALVE:
|
||||
valves[tokens[0]] = {'id': tokens[0], 'node1': tokens[1], 'node2': tokens[2], 'diameter': tokens[3], 'v_type': tokens[4], 'setting': tokens[5], 'minor_loss': tokens[6]}
|
||||
_7_valves[tokens[0]] = {'id': tokens[0], 'node1': tokens[1], 'node2': tokens[2], 'diameter': tokens[3], 'v_type': tokens[4], 'setting': tokens[5], 'minor_loss': tokens[6]}
|
||||
continue
|
||||
elif section == 'demand':
|
||||
demand_pattern = tokens[2] if tokens_len >= 3 else None
|
||||
demand_category = tokens[3] if tokens_len == 4 else None
|
||||
demands[tokens[0]].append({'demand': tokens[1], 'pattern': demand_pattern, 'category': demand_category})
|
||||
_9_demands[tokens[0]].append({'demand': tokens[1], 'pattern': demand_pattern, 'category': demand_category})
|
||||
continue
|
||||
elif section == 'status':
|
||||
if tokens[0] not in status:
|
||||
status[tokens[0]] = {}
|
||||
if tokens[0] not in _10_status:
|
||||
_10_status[tokens[0]] = {}
|
||||
setting = None
|
||||
try:
|
||||
setting = float(tokens[1])
|
||||
except:
|
||||
setting = None
|
||||
if setting != None:
|
||||
status[tokens[0]]['setting'] = setting
|
||||
_10_status[tokens[0]]['setting'] = setting
|
||||
else:
|
||||
status[tokens[0]]['status'] = tokens[1].upper()
|
||||
_10_status[tokens[0]]['status'] = tokens[1].upper()
|
||||
continue
|
||||
elif section == PATTERN:
|
||||
if tokens[0] not in patterns:
|
||||
patterns[tokens[0]] = []
|
||||
if tokens[0] not in _11_patterns:
|
||||
_11_patterns[tokens[0]] = []
|
||||
for i in range(1, tokens_len):
|
||||
patterns[tokens[0]].append(float(tokens[i]))
|
||||
_11_patterns[tokens[0]].append(float(tokens[i]))
|
||||
continue
|
||||
elif section == CURVE:
|
||||
if tokens[0] not in curves:
|
||||
curves[tokens[0]] = []
|
||||
if tokens[0] not in _12_curves:
|
||||
_12_curves[tokens[0]] = []
|
||||
for i in range(1, tokens_len, 2):
|
||||
curves[tokens[0]].append({ 'x': float(tokens[i]), 'y': float(tokens[i + 1]) })
|
||||
_12_curves[tokens[0]].append({ 'x': float(tokens[i]), 'y': float(tokens[i + 1]) })
|
||||
continue
|
||||
elif section == 'emitter':
|
||||
emitters[tokens[0]] = float(tokens[1])
|
||||
_16_emitters[tokens[0]] = float(tokens[1])
|
||||
continue
|
||||
elif section == 'time':
|
||||
if tokens_len == 2:
|
||||
times[tokens[0]] = tokens[1]
|
||||
_21_times[tokens[0]] = tokens[1]
|
||||
elif tokens_len == 3:
|
||||
times[tokens[0] + ' ' + tokens[1]] = tokens[2]
|
||||
_21_times[tokens[0] + ' ' + tokens[1]] = tokens[2]
|
||||
elif tokens_len == 4:
|
||||
times[tokens[0] + ' ' + tokens[1]] = tokens[2] + ' ' + tokens[3]
|
||||
_21_times[tokens[0] + ' ' + tokens[1]] = tokens[2] + ' ' + tokens[3]
|
||||
continue
|
||||
elif section == 'option':
|
||||
if tokens[0] == 'HYDRAULICS' or tokens[0] == 'MAP':
|
||||
continue
|
||||
if tokens_len == 2:
|
||||
options[tokens[0]] = tokens[1]
|
||||
_22_options[tokens[0]] = tokens[1]
|
||||
elif tokens_len == 3:
|
||||
if tokens[0] == 'UNBALANCED' or tokens[0] == 'QUALITY':
|
||||
options[tokens[0]] = tokens[1] + ' ' + tokens[2]
|
||||
_22_options[tokens[0]] = tokens[1] + ' ' + tokens[2]
|
||||
else:
|
||||
options[tokens[0] + ' ' + tokens[1]] = tokens[2]
|
||||
_22_options[tokens[0] + ' ' + tokens[1]] = tokens[2]
|
||||
continue
|
||||
elif section == 'coordinate':
|
||||
if tokens[0] in junctions:
|
||||
junctions[tokens[0]] |= {'x': tokens[1], 'y': tokens[2]}
|
||||
elif tokens[0] in reservoirs:
|
||||
reservoirs[tokens[0]] |= {'x': tokens[1], 'y': tokens[2]}
|
||||
elif tokens[0] in tanks:
|
||||
tanks[tokens[0]] |= {'x': tokens[1], 'y': tokens[2]}
|
||||
if tokens[0] in _2_junctions:
|
||||
_2_junctions[tokens[0]] |= {'x': tokens[1], 'y': tokens[2]}
|
||||
elif tokens[0] in _3_reservoirs:
|
||||
_3_reservoirs[tokens[0]] |= {'x': tokens[1], 'y': tokens[2]}
|
||||
elif tokens[0] in _4_tanks:
|
||||
_4_tanks[tokens[0]] |= {'x': tokens[1], 'y': tokens[2]}
|
||||
continue
|
||||
|
||||
# title
|
||||
set_title(name, ChangeSet({ 'value': title }))
|
||||
set_title(name, ChangeSet({ 'value': _1_title }))
|
||||
|
||||
# pattern
|
||||
for key, value in patterns.items():
|
||||
for key, value in _11_patterns.items():
|
||||
set_pattern(name, ChangeSet({'id': key, 'factors': value}))
|
||||
|
||||
# curve
|
||||
for key, value in curves.items():
|
||||
for key, value in _12_curves.items():
|
||||
set_curve(name, ChangeSet({'id': key, 'coords': value}))
|
||||
|
||||
# junction
|
||||
for value in junctions.values():
|
||||
for value in _2_junctions.values():
|
||||
if 'x' not in value:
|
||||
value['x'] = 0.0
|
||||
if 'y' not in value:
|
||||
@@ -222,7 +277,7 @@ def read_inp(name: str, inp: str):
|
||||
add_junction(name, ChangeSet(value))
|
||||
|
||||
# reservoir
|
||||
for value in reservoirs.values():
|
||||
for value in _3_reservoirs.values():
|
||||
if 'x' not in value:
|
||||
value['x'] = 0.0
|
||||
if 'y' not in value:
|
||||
@@ -230,7 +285,7 @@ def read_inp(name: str, inp: str):
|
||||
add_reservoir(name, ChangeSet(value))
|
||||
|
||||
# tank
|
||||
for value in tanks.values():
|
||||
for value in _4_tanks.values():
|
||||
if 'x' not in value:
|
||||
value['x'] = 0.0
|
||||
if 'y' not in value:
|
||||
@@ -238,33 +293,33 @@ def read_inp(name: str, inp: str):
|
||||
add_tank(name, ChangeSet(value))
|
||||
|
||||
# pipe
|
||||
for value in pipes.values():
|
||||
for value in _5_pipes.values():
|
||||
add_pipe(name, ChangeSet(value))
|
||||
|
||||
# pump
|
||||
for value in pumps.values():
|
||||
for value in _6_pumps.values():
|
||||
add_pump(name, ChangeSet(value))
|
||||
|
||||
# valve
|
||||
for value in valves.values():
|
||||
for value in _7_valves.values():
|
||||
add_valve(name, ChangeSet(value))
|
||||
|
||||
# demand
|
||||
for key, value in demands.items():
|
||||
for key, value in _9_demands.items():
|
||||
set_demand(name, ChangeSet({'junction': key, 'demands': value}))
|
||||
|
||||
# status
|
||||
for key, value in status.items():
|
||||
for key, value in _10_status.items():
|
||||
set_status(name, ChangeSet({'link': key} | value))
|
||||
|
||||
# emitter
|
||||
for key, value in emitters.items():
|
||||
for key, value in _16_emitters.items():
|
||||
set_emitter(name, ChangeSet({'junction': key, 'coefficient': value}))
|
||||
|
||||
# time
|
||||
set_time(name, ChangeSet(times))
|
||||
set_time(name, ChangeSet(_21_times))
|
||||
|
||||
# option
|
||||
set_option(name, ChangeSet(options))
|
||||
set_option(name, ChangeSet(_22_options))
|
||||
|
||||
close_project(name)
|
||||
443
api/command.py
443
api/command.py
@@ -5,30 +5,127 @@ from .s4_tanks import *
|
||||
from .s5_pipes import *
|
||||
from .s6_pumps import *
|
||||
from .s7_valves import *
|
||||
from .s8_tags import *
|
||||
from .s9_demands import *
|
||||
from .s10_status import *
|
||||
from .s11_patterns import *
|
||||
from .s12_curves import *
|
||||
from .s13_controls import *
|
||||
from .s14_rules import *
|
||||
from .s15_energy import *
|
||||
from .s16_emitters import *
|
||||
from .s17_quality import *
|
||||
from .s18_sources import *
|
||||
from .s19_reactions import *
|
||||
from .s20_mixing import *
|
||||
from .s21_times import *
|
||||
from .s22_report import *
|
||||
from .s23_options import *
|
||||
from .s24_coordinates import *
|
||||
from .s25_vertices import *
|
||||
from .s26_labels import *
|
||||
from .s27_backdrop import *
|
||||
from .s28_end import *
|
||||
|
||||
|
||||
_s1_title = 'title'
|
||||
_s2_junction = 'junction'
|
||||
_s3_reservoir = 'reservoir'
|
||||
_s4_tank = 'tank'
|
||||
_s5_pipe = 'pipe'
|
||||
_s6_pump = 'pump'
|
||||
_s7_valve = 'valve'
|
||||
_s8_tag = 'tag'
|
||||
_s9_demand = 'demand'
|
||||
_s10_status = 'status'
|
||||
_s11_pattern = 'patten'
|
||||
_s12_curve = 'curve'
|
||||
_s13_control = 'control'
|
||||
_s14_rule = 'rule'
|
||||
_s15_global_energy = 'global_energy'
|
||||
_s15_pump_energy = 'pump_energy'
|
||||
_s16_emitter = 'emitter'
|
||||
_s17_quality = 'quality'
|
||||
_s18_source = 'source'
|
||||
_s19_global_reaction = 'global_reaction'
|
||||
_s19_pipe_reaction = 'pipe_reaction'
|
||||
_s19_tank_reaction = 'tank_reaction'
|
||||
_s20_mixing = 'mixing'
|
||||
_s21_time = 'time'
|
||||
_s22_report = 'report'
|
||||
_s23_option = 'option'
|
||||
_s24_coordinate = 'coordinate'
|
||||
_s25_vertex = 'vertex'
|
||||
_s26_label = 'label'
|
||||
_s27_backdrop = 'backdrop'
|
||||
_s28_end = 'end'
|
||||
|
||||
|
||||
def execute_add_command(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
type = cs.operations[0]['type']
|
||||
|
||||
if type == JUNCTION:
|
||||
if type == _s1_title:
|
||||
return ChangeSet()
|
||||
if type == _s2_junction:
|
||||
return add_junction(name, cs)
|
||||
elif type == RESERVOIR:
|
||||
elif type == _s3_reservoir:
|
||||
return add_reservoir(name, cs)
|
||||
elif type == TANK:
|
||||
elif type == _s4_tank:
|
||||
return add_tank(name, cs)
|
||||
elif type == PIPE:
|
||||
elif type == _s5_pipe:
|
||||
return add_pipe(name, cs)
|
||||
elif type == PUMP:
|
||||
elif type == _s6_pump:
|
||||
return add_pump(name, cs)
|
||||
elif type == VALVE:
|
||||
elif type == _s7_valve:
|
||||
return add_valve(name, cs)
|
||||
elif type == _s8_tag:
|
||||
return ChangeSet()
|
||||
elif type == _s9_demand:
|
||||
return ChangeSet()
|
||||
elif type == _s10_status:
|
||||
return ChangeSet()
|
||||
elif type == _s11_pattern:
|
||||
return add_pattern(name, cs)
|
||||
elif type == _s12_curve:
|
||||
return add_curve(name, cs)
|
||||
elif type == _s13_control:
|
||||
return ChangeSet()
|
||||
elif type == _s14_rule:
|
||||
return ChangeSet()
|
||||
elif type == _s15_global_energy:
|
||||
return ChangeSet()
|
||||
elif type == _s15_pump_energy:
|
||||
return ChangeSet()
|
||||
elif type == _s16_emitter:
|
||||
return ChangeSet()
|
||||
elif type == _s17_quality:
|
||||
return ChangeSet()
|
||||
elif type == _s18_source:
|
||||
return add_source(name, cs)
|
||||
elif type == _s19_global_reaction:
|
||||
return ChangeSet()
|
||||
elif type == _s19_pipe_reaction:
|
||||
return ChangeSet()
|
||||
elif type == _s19_tank_reaction:
|
||||
return ChangeSet()
|
||||
elif type == _s20_mixing:
|
||||
return add_mixing(name, cs)
|
||||
elif type == _s21_time:
|
||||
return ChangeSet()
|
||||
elif type == _s22_report:
|
||||
return ChangeSet()
|
||||
elif type == _s23_option:
|
||||
return ChangeSet()
|
||||
elif type == _s24_coordinate:
|
||||
return ChangeSet()
|
||||
elif type == _s25_vertex:
|
||||
return add_vertex(name, cs)
|
||||
elif type == _s26_label:
|
||||
return add_label(name, cs)
|
||||
elif type == _s27_backdrop:
|
||||
return ChangeSet()
|
||||
elif type == _s28_end:
|
||||
return ChangeSet()
|
||||
|
||||
return ChangeSet()
|
||||
|
||||
@@ -36,34 +133,68 @@ def execute_add_command(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
def execute_update_command(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
type = cs.operations[0]['type']
|
||||
|
||||
if type == 'title':
|
||||
if type == _s1_title:
|
||||
return set_title(name, cs)
|
||||
if type == JUNCTION:
|
||||
if type == _s2_junction:
|
||||
return set_junction(name, cs)
|
||||
elif type == RESERVOIR:
|
||||
elif type == _s3_reservoir:
|
||||
return set_reservoir(name, cs)
|
||||
elif type == TANK:
|
||||
elif type == _s4_tank:
|
||||
return set_tank(name, cs)
|
||||
elif type == PIPE:
|
||||
elif type == _s5_pipe:
|
||||
return set_pipe(name, cs)
|
||||
elif type == PUMP:
|
||||
elif type == _s6_pump:
|
||||
return set_pump(name, cs)
|
||||
elif type == VALVE:
|
||||
elif type == _s7_valve:
|
||||
return set_valve(name, cs)
|
||||
elif type == 'demand':
|
||||
return set_demand(name, cs)
|
||||
elif type == 'status':
|
||||
elif type == _s8_tag:
|
||||
return set_tag(name, cs)
|
||||
elif type == _s9_demand: # exception, batch command ...
|
||||
return ChangeSet()
|
||||
elif type == _s10_status:
|
||||
return set_status(name, cs)
|
||||
elif type == PATTERN:
|
||||
elif type == _s11_pattern:
|
||||
return set_pattern(name, cs)
|
||||
elif type == CURVE:
|
||||
elif type == _s12_curve:
|
||||
return set_curve(name, cs)
|
||||
elif type == 'emitter':
|
||||
elif type == _s13_control:
|
||||
return set_control(name, cs)
|
||||
elif type == _s14_rule:
|
||||
return set_rule(name, cs)
|
||||
elif type == _s15_global_energy:
|
||||
return set_global_energy(name, cs)
|
||||
elif type == _s15_pump_energy:
|
||||
return set_pump_energy(name, cs)
|
||||
elif type == _s16_emitter:
|
||||
return set_emitter(name, cs)
|
||||
elif type == 'time':
|
||||
elif type == _s17_quality:
|
||||
return set_quality(name, cs)
|
||||
elif type == _s18_source:
|
||||
return set_source(name, cs)
|
||||
elif type == _s19_global_reaction:
|
||||
return set_global_reaction(name, cs)
|
||||
elif type == _s19_pipe_reaction:
|
||||
return set_pipe_reaction(name, cs)
|
||||
elif type == _s19_tank_reaction:
|
||||
return set_tank_reaction(name, cs)
|
||||
elif type == _s20_mixing:
|
||||
return set_mixing(name, cs)
|
||||
elif type == _s21_time:
|
||||
return set_time(name, cs)
|
||||
elif type == 'option':
|
||||
elif type == _s22_report: # no api now
|
||||
return ChangeSet()
|
||||
elif type == _s23_option:
|
||||
return set_option(name, cs)
|
||||
elif type == _s24_coordinate: # do not support update here
|
||||
return ChangeSet()
|
||||
elif type == _s25_vertex:
|
||||
return set_vertex(name, cs)
|
||||
elif type == _s26_label:
|
||||
return set_label(name, cs)
|
||||
elif type == _s27_backdrop:
|
||||
return set_backdrop(name, cs)
|
||||
elif type == _s28_end: # end
|
||||
return ChangeSet()
|
||||
|
||||
return ChangeSet()
|
||||
|
||||
@@ -71,18 +202,68 @@ def execute_update_command(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
def execute_delete_command(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
type = cs.operations[0]['type']
|
||||
|
||||
if type == JUNCTION:
|
||||
if type == _s1_title:
|
||||
return ChangeSet()
|
||||
if type == _s2_junction:
|
||||
return delete_junction(name, cs)
|
||||
elif type == RESERVOIR:
|
||||
elif type == _s3_reservoir:
|
||||
return delete_reservoir(name, cs)
|
||||
elif type == TANK:
|
||||
elif type == _s4_tank:
|
||||
return delete_tank(name, cs)
|
||||
elif type == PIPE:
|
||||
elif type == _s5_pipe:
|
||||
return delete_pipe(name, cs)
|
||||
elif type == PUMP:
|
||||
elif type == _s6_pump:
|
||||
return delete_pump(name, cs)
|
||||
elif type == VALVE:
|
||||
elif type == _s7_valve:
|
||||
return delete_valve(name, cs)
|
||||
elif type == _s8_tag:
|
||||
return ChangeSet()
|
||||
elif type == _s9_demand:
|
||||
return ChangeSet()
|
||||
elif type == _s10_status:
|
||||
return ChangeSet()
|
||||
elif type == _s11_pattern:
|
||||
return delete_pattern(name, cs)
|
||||
elif type == _s12_curve:
|
||||
return delete_curve(name, cs)
|
||||
elif type == _s13_control:
|
||||
return ChangeSet()
|
||||
elif type == _s14_rule:
|
||||
return ChangeSet()
|
||||
elif type == _s15_global_energy:
|
||||
return ChangeSet()
|
||||
elif type == _s15_pump_energy:
|
||||
return ChangeSet()
|
||||
elif type == _s16_emitter:
|
||||
return ChangeSet()
|
||||
elif type == _s17_quality:
|
||||
return ChangeSet()
|
||||
elif type == _s18_source:
|
||||
return delete_source(name, cs)
|
||||
elif type == _s19_global_reaction:
|
||||
return ChangeSet()
|
||||
elif type == _s19_pipe_reaction:
|
||||
return ChangeSet()
|
||||
elif type == _s19_tank_reaction:
|
||||
return ChangeSet()
|
||||
elif type == _s20_mixing:
|
||||
return delete_mixing(name, cs)
|
||||
elif type == _s21_time:
|
||||
return ChangeSet()
|
||||
elif type == _s22_report:
|
||||
return ChangeSet()
|
||||
elif type == _s23_option:
|
||||
return ChangeSet()
|
||||
elif type == _s24_coordinate:
|
||||
return ChangeSet()
|
||||
elif type == _s25_vertex:
|
||||
return delete_vertex(name, cs)
|
||||
elif type == _s26_label:
|
||||
return delete_label(name, cs)
|
||||
elif type == _s27_backdrop:
|
||||
return ChangeSet()
|
||||
elif type == _s28_end:
|
||||
return ChangeSet()
|
||||
|
||||
return ChangeSet()
|
||||
|
||||
@@ -108,18 +289,68 @@ def execute_batch_commands(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
def cache_add_command(name: str, cs: ChangeSet) -> SqlChangeSet | None:
|
||||
type = cs.operations[0]['type']
|
||||
|
||||
if type == JUNCTION:
|
||||
if type == _s1_title:
|
||||
return None
|
||||
if type == _s2_junction:
|
||||
return add_junction_cache(name, cs)
|
||||
elif type == RESERVOIR:
|
||||
elif type == _s3_reservoir:
|
||||
return add_reservoir_cache(name, cs)
|
||||
elif type == TANK:
|
||||
elif type == _s4_tank:
|
||||
return add_tank_cache(name, cs)
|
||||
elif type == PIPE:
|
||||
elif type == _s5_pipe:
|
||||
return add_pipe_cache(name, cs)
|
||||
elif type == PUMP:
|
||||
elif type == _s6_pump:
|
||||
return add_pump_cache(name, cs)
|
||||
elif type == VALVE:
|
||||
elif type == _s7_valve:
|
||||
return add_valve_cache(name, cs)
|
||||
elif type == _s8_tag:
|
||||
return None
|
||||
elif type == _s9_demand:
|
||||
return None
|
||||
elif type == _s10_status:
|
||||
return None
|
||||
elif type == _s11_pattern:
|
||||
return add_pattern_cache(name, cs)
|
||||
elif type == _s12_curve:
|
||||
return add_curve_cache(name, cs)
|
||||
elif type == _s13_control:
|
||||
return None
|
||||
elif type == _s14_rule:
|
||||
return None
|
||||
elif type == _s15_global_energy:
|
||||
return None
|
||||
elif type == _s15_pump_energy:
|
||||
return None
|
||||
elif type == _s16_emitter:
|
||||
return None
|
||||
elif type == _s17_quality:
|
||||
return None
|
||||
elif type == _s18_source:
|
||||
return add_source_cache(name, cs)
|
||||
elif type == _s19_global_reaction:
|
||||
return None
|
||||
elif type == _s19_pipe_reaction:
|
||||
return None
|
||||
elif type == _s19_tank_reaction:
|
||||
return None
|
||||
elif type == _s20_mixing:
|
||||
return add_mixing_cache(name, cs)
|
||||
elif type == _s21_time:
|
||||
return None
|
||||
elif type == _s22_report:
|
||||
return None
|
||||
elif type == _s23_option:
|
||||
return None
|
||||
elif type == _s24_coordinate:
|
||||
return None
|
||||
elif type == _s25_vertex:
|
||||
return add_vertex_cache(name, cs)
|
||||
elif type == _s26_label:
|
||||
return add_label_cache(name, cs)
|
||||
elif type == _s27_backdrop:
|
||||
return None
|
||||
elif type == _s28_end:
|
||||
return None
|
||||
|
||||
return None
|
||||
|
||||
@@ -127,34 +358,68 @@ def cache_add_command(name: str, cs: ChangeSet) -> SqlChangeSet | None:
|
||||
def cache_update_command(name: str, cs: ChangeSet) -> SqlChangeSet | None:
|
||||
type = cs.operations[0]['type']
|
||||
|
||||
if type == 'title':
|
||||
if type == _s1_title:
|
||||
return set_title_cache(name, cs)
|
||||
if type == JUNCTION:
|
||||
if type == _s2_junction:
|
||||
return set_junction_cache(name, cs)
|
||||
elif type == RESERVOIR:
|
||||
elif type == _s3_reservoir:
|
||||
return set_reservoir_cache(name, cs)
|
||||
elif type == TANK:
|
||||
elif type == _s4_tank:
|
||||
return set_tank_cache(name, cs)
|
||||
elif type == PIPE:
|
||||
elif type == _s5_pipe:
|
||||
return set_pipe_cache(name, cs)
|
||||
elif type == PUMP:
|
||||
elif type == _s6_pump:
|
||||
return set_pump_cache(name, cs)
|
||||
elif type == VALVE:
|
||||
elif type == _s7_valve:
|
||||
return set_valve_cache(name, cs)
|
||||
elif type == 'demand':
|
||||
return set_demand_cache(name, cs)
|
||||
elif type == 'status':
|
||||
elif type == _s8_tag:
|
||||
return set_tag_cache(name, cs)
|
||||
elif type == _s9_demand: # exception, batch command ...
|
||||
return None
|
||||
elif type == _s10_status:
|
||||
return set_status_cache(name, cs)
|
||||
elif type == PATTERN:
|
||||
elif type == _s11_pattern:
|
||||
return set_pattern_cache(name, cs)
|
||||
elif type == CURVE:
|
||||
elif type == _s12_curve:
|
||||
return set_curve_cache(name, cs)
|
||||
elif type == 'emitter':
|
||||
elif type == _s13_control:
|
||||
return set_control_cache(name, cs)
|
||||
elif type == _s14_rule:
|
||||
return set_rule_cache(name, cs)
|
||||
elif type == _s15_global_energy:
|
||||
return set_global_energy_cache(name, cs)
|
||||
elif type == _s15_pump_energy:
|
||||
return set_pump_energy_cache(name, cs)
|
||||
elif type == _s16_emitter:
|
||||
return set_emitter_cache(name, cs)
|
||||
elif type == 'time':
|
||||
elif type == _s17_quality:
|
||||
return set_quality_cache(name, cs)
|
||||
elif type == _s18_source:
|
||||
return set_source_cache(name, cs)
|
||||
elif type == _s19_global_reaction:
|
||||
return set_global_reaction_cache(name, cs)
|
||||
elif type == _s19_pipe_reaction:
|
||||
return set_pipe_reaction_cache(name, cs)
|
||||
elif type == _s19_tank_reaction:
|
||||
return set_tank_reaction_cache(name, cs)
|
||||
elif type == _s20_mixing:
|
||||
return set_mixing_cache(name, cs)
|
||||
elif type == _s21_time:
|
||||
return set_time_cache(name, cs)
|
||||
elif type == 'option':
|
||||
elif type == _s22_report: # no api now
|
||||
return None
|
||||
elif type == _s23_option:
|
||||
return set_option_cache(name, cs)
|
||||
elif type == _s24_coordinate: # do not support update here
|
||||
return None
|
||||
elif type == _s25_vertex:
|
||||
return set_vertex_cache(name, cs)
|
||||
elif type == _s26_label:
|
||||
return set_label_cache(name, cs)
|
||||
elif type == _s27_backdrop:
|
||||
return set_backdrop_cache(name, cs)
|
||||
elif type == _s28_end: # end
|
||||
return None
|
||||
|
||||
return None
|
||||
|
||||
@@ -162,18 +427,68 @@ def cache_update_command(name: str, cs: ChangeSet) -> SqlChangeSet | None:
|
||||
def cache_delete_command(name: str, cs: ChangeSet) -> SqlChangeSet | None:
|
||||
type = cs.operations[0]['type']
|
||||
|
||||
if type == JUNCTION:
|
||||
if type == _s1_title:
|
||||
return None
|
||||
if type == _s2_junction:
|
||||
return delete_junction_cache(name, cs)
|
||||
elif type == RESERVOIR:
|
||||
elif type == _s3_reservoir:
|
||||
return delete_reservoir_cache(name, cs)
|
||||
elif type == TANK:
|
||||
elif type == _s4_tank:
|
||||
return delete_tank_cache(name, cs)
|
||||
elif type == PIPE:
|
||||
elif type == _s5_pipe:
|
||||
return delete_pipe_cache(name, cs)
|
||||
elif type == PUMP:
|
||||
elif type == _s6_pump:
|
||||
return delete_pump_cache(name, cs)
|
||||
elif type == VALVE:
|
||||
elif type == _s7_valve:
|
||||
return delete_valve_cache(name, cs)
|
||||
elif type == _s8_tag:
|
||||
return None
|
||||
elif type == _s9_demand:
|
||||
return None
|
||||
elif type == _s10_status:
|
||||
return None
|
||||
elif type == _s11_pattern:
|
||||
return delete_pattern_cache(name, cs)
|
||||
elif type == _s12_curve:
|
||||
return delete_curve_cache(name, cs)
|
||||
elif type == _s13_control:
|
||||
return None
|
||||
elif type == _s14_rule:
|
||||
return None
|
||||
elif type == _s15_global_energy:
|
||||
return None
|
||||
elif type == _s15_pump_energy:
|
||||
return None
|
||||
elif type == _s16_emitter:
|
||||
return None
|
||||
elif type == _s17_quality:
|
||||
return None
|
||||
elif type == _s18_source:
|
||||
return delete_source_cache(name, cs)
|
||||
elif type == _s19_global_reaction:
|
||||
return None
|
||||
elif type == _s19_pipe_reaction:
|
||||
return None
|
||||
elif type == _s19_tank_reaction:
|
||||
return None
|
||||
elif type == _s20_mixing:
|
||||
return delete_mixing_cache(name, cs)
|
||||
elif type == _s21_time:
|
||||
return None
|
||||
elif type == _s22_report:
|
||||
return None
|
||||
elif type == _s23_option:
|
||||
return None
|
||||
elif type == _s24_coordinate:
|
||||
return None
|
||||
elif type == _s25_vertex:
|
||||
return delete_vertex_cache(name, cs)
|
||||
elif type == _s26_label:
|
||||
return delete_label_cache(name, cs)
|
||||
elif type == _s27_backdrop:
|
||||
return None
|
||||
elif type == _s28_end:
|
||||
return None
|
||||
|
||||
return None
|
||||
|
||||
@@ -189,21 +504,33 @@ def execute_batch_command(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
operation = op['operation']
|
||||
|
||||
r = None
|
||||
demand = None
|
||||
|
||||
if operation == API_ADD:
|
||||
r = cache_add_command(name, ChangeSet(op))
|
||||
elif operation == API_UPDATE:
|
||||
r = cache_update_command(name, ChangeSet(op))
|
||||
if op['type'] == 'demand':
|
||||
r = set_demand_cache(name, ChangeSet(op))
|
||||
elif operation == API_DELETE:
|
||||
r = cache_delete_command(name, ChangeSet(op))
|
||||
|
||||
if r == None:
|
||||
return ChangeSet()
|
||||
|
||||
redo_sql_s.append(r.redo_sql)
|
||||
undo_sql_s.append(r.undo_sql)
|
||||
redo_cs_s.append(r.redo_cs)
|
||||
undo_cs_s.append(r.undo_cs)
|
||||
if op['type'] == 'demand':
|
||||
redo_sql_s.append(r.redo_sql)
|
||||
undo_sql_s.append(r.undo_sql)
|
||||
for d in r.redo_cs:
|
||||
redo_cs_s.append(d)
|
||||
for d in r.undo_cs.reverse(): # need reverse again...
|
||||
undo_cs_s.append(r.undo_cs)
|
||||
else:
|
||||
redo_sql_s.append(r.redo_sql)
|
||||
undo_sql_s.append(r.undo_sql)
|
||||
redo_cs_s.append(r.redo_cs)
|
||||
undo_cs_s.append(r.undo_cs)
|
||||
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
@@ -43,14 +43,14 @@ class ChangeSet:
|
||||
|
||||
|
||||
class SqlChangeSet:
|
||||
def __init__(self, redo_sql: str, undo_sql: str, redo_cs: dict[str, str], undo_cs: dict[str, str]) -> None:
|
||||
def __init__(self, redo_sql: str, undo_sql: str, redo_cs: dict[str, Any], undo_cs: dict[str, Any]) -> None:
|
||||
self.redo_sql = redo_sql
|
||||
self.undo_sql = undo_sql
|
||||
self.redo_cs = redo_cs
|
||||
self.undo_cs = undo_cs
|
||||
|
||||
class BatchSqlChangeSet:
|
||||
def __init__(self, redo_sql: str, undo_sql: str, redo_cs: list[dict[str, str]], undo_cs: list[dict[str, str]]) -> None:
|
||||
def __init__(self, redo_sql: str, undo_sql: str, redo_cs: list[dict[str, Any]], undo_cs: list[dict[str, Any]]) -> None:
|
||||
self.redo_sql = redo_sql
|
||||
self.undo_sql = undo_sql
|
||||
self.redo_cs = redo_cs
|
||||
|
||||
@@ -66,3 +66,58 @@ def set_status_cache(name: str, cs: ChangeSet) -> SqlChangeSet:
|
||||
|
||||
def set_status(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return execute_command(name, set_status_cache(name, cs))
|
||||
|
||||
|
||||
class InpStatus:
|
||||
def __init__(self, line: str) -> None:
|
||||
tokens = line.split()
|
||||
|
||||
num = len(tokens)
|
||||
has_desc = tokens[-1].startswith(';')
|
||||
num_without_desc = (num - 1) if has_desc else num
|
||||
|
||||
self.link = str(tokens[0])
|
||||
self.value = tokens[1]
|
||||
self.is_status = True
|
||||
if self.value == LINK_STATUS_OPEN or self.value == LINK_STATUS_CLOSED or self.value == LINK_STATUS_ACTIVE:
|
||||
self.status = str(self.value)
|
||||
else:
|
||||
self.setting = float(self.value)
|
||||
self.is_status = False
|
||||
|
||||
|
||||
def inp_in_status(section: list[str]) -> ChangeSet:
|
||||
objs: dict[str, list[InpStatus]] = {}
|
||||
for s in section:
|
||||
# skip comment
|
||||
if s.startswith(';'):
|
||||
continue
|
||||
obj = InpStatus(s)
|
||||
if obj.link not in objs:
|
||||
objs[obj.link] = []
|
||||
objs[obj.link].append(obj)
|
||||
|
||||
cs = ChangeSet()
|
||||
for link, values in objs.items():
|
||||
obj_cs = {'operation': API_UPDATE, 'type': 'status', 'link' : link, 'status': None, 'setting': None}
|
||||
for obj in values:
|
||||
if obj.is_status:
|
||||
obj_cs['status'] = obj.status
|
||||
else:
|
||||
obj_cs['setting'] = obj.setting
|
||||
cs.append(obj_cs)
|
||||
return cs
|
||||
|
||||
|
||||
def inp_out_status(name: str) -> list[str]:
|
||||
lines = []
|
||||
objs = read_all(name, 'select * from status')
|
||||
for obj in objs:
|
||||
link = obj['link']
|
||||
status = obj['status'] if obj['status'] != None else ''
|
||||
setting = obj['setting'] if obj['setting'] != None else ''
|
||||
if status != '':
|
||||
lines.append(f'{link} {status}')
|
||||
if setting != '':
|
||||
lines.append(f'{link} {setting}')
|
||||
return lines
|
||||
|
||||
@@ -91,3 +91,39 @@ def delete_pattern_cache(name: str, cs: ChangeSet) -> SqlChangeSet:
|
||||
|
||||
def delete_pattern(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return execute_command(name, delete_pattern_cache(name, cs))
|
||||
|
||||
|
||||
def inp_in_pattern(section: list[str]) -> ChangeSet:
|
||||
descs = {}
|
||||
patterns: dict[str, list[float]] = {}
|
||||
|
||||
count = len(section)
|
||||
for i in range(0, count):
|
||||
if section[i].startswith(';'):
|
||||
# this is description
|
||||
next = i + 1
|
||||
if next < count and section[next].startswith(';') == False:
|
||||
next_tokens = section[next].split()
|
||||
descs[next_tokens[0]] = section[i].removeprefix(';')
|
||||
continue
|
||||
|
||||
tokens = section[i].split()
|
||||
if tokens[0] not in patterns:
|
||||
patterns[tokens[0]] = []
|
||||
for token in tokens[1:]:
|
||||
patterns[tokens[0]].append(float(token))
|
||||
|
||||
cs = ChangeSet()
|
||||
for id, factors in patterns.items():
|
||||
cs.append({'operation': API_ADD, 'type': 'pattern', 'id' : id, 'factors' : factors})
|
||||
return cs
|
||||
|
||||
|
||||
def inp_out_pattern(name: str) -> list[str]:
|
||||
lines = []
|
||||
objs = read_all(name, f"select * from patterns order by _order")
|
||||
for obj in objs:
|
||||
id = obj['id']
|
||||
factor = obj['factor']
|
||||
lines.append(f'{id} {factor}')
|
||||
return lines
|
||||
|
||||
@@ -119,3 +119,50 @@ def delete_curve_cache(name: str, cs: ChangeSet) -> SqlChangeSet:
|
||||
|
||||
def delete_curve(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return execute_command(name, delete_curve_cache(name, cs))
|
||||
|
||||
|
||||
def inp_in_curve(section: list[str]) -> ChangeSet:
|
||||
types = {}
|
||||
descs = {}
|
||||
curves: dict[str, list[dict[str, float]]] = {}
|
||||
|
||||
count = len(section)
|
||||
for i in range(0, count):
|
||||
if section[i].startswith(';'):
|
||||
# this is description
|
||||
type_plus_desc = section[i].removeprefix(';')
|
||||
type_plus_desc_tokens = type_plus_desc.split(':')
|
||||
next = i + 1
|
||||
if next < count and section[next].startswith(';') == False:
|
||||
next_tokens = section[next].split()
|
||||
types[next_tokens[0]] = type_plus_desc_tokens[0].strip()
|
||||
if len(type_plus_desc_tokens) > 1:
|
||||
descs[next_tokens[0]] = type_plus_desc_tokens[1].strip()
|
||||
continue
|
||||
|
||||
tokens = section[i].split()
|
||||
if tokens[0] not in curves:
|
||||
curves[tokens[0]] = []
|
||||
curves[tokens[0]].append({'x': float(tokens[1]), 'y': float(tokens[2])})
|
||||
|
||||
cs = ChangeSet()
|
||||
for id, coords in curves.items():
|
||||
c_type = types[id] if id in types else CURVE_TYPE_PUMP
|
||||
cs.append({'operation': API_ADD, 'type': 'curve', 'id' : id, 'c_type': c_type, 'coords' : coords})
|
||||
return cs
|
||||
|
||||
|
||||
def inp_out_curve(name: str) -> list[str]:
|
||||
lines = []
|
||||
types = read_all(name, f"select * from _curve")
|
||||
for type in types:
|
||||
id = type['id']
|
||||
# ;type: desc
|
||||
lines.append(f";{type['type']}:")
|
||||
objs = read_all(name, f"select * from curves where id = '{id}' order by _order")
|
||||
for obj in objs:
|
||||
id = obj['id']
|
||||
x = obj['x']
|
||||
y = obj['y']
|
||||
lines.append(f'{id} {x} {y}')
|
||||
return lines
|
||||
|
||||
@@ -24,3 +24,19 @@ def set_control_cache(name: str, cs: ChangeSet) -> SqlChangeSet:
|
||||
|
||||
def set_control(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return execute_command(name, set_control_cache(name, cs))
|
||||
|
||||
|
||||
class InpControl:
|
||||
def __init__(self, section) -> None:
|
||||
self.control = '\n'.join(section)
|
||||
|
||||
|
||||
def inp_in_control(section: list[str]) -> ChangeSet:
|
||||
obj = InpControl(section)
|
||||
cs = ChangeSet({'operation' : API_UPDATE, 'type': 'control', 'control' : obj.control})
|
||||
return cs
|
||||
|
||||
|
||||
def inp_out_control(name: str) -> list[str]:
|
||||
obj = str(get_control(name)['control'])
|
||||
return obj.split('\n')
|
||||
|
||||
@@ -24,3 +24,19 @@ def set_rule_cache(name: str, cs: ChangeSet) -> SqlChangeSet:
|
||||
|
||||
def set_rule(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return execute_command(name, set_rule_cache(name, cs))
|
||||
|
||||
|
||||
class InpRule:
|
||||
def __init__(self, section) -> None:
|
||||
self.rule = '\n'.join(section)
|
||||
|
||||
|
||||
def inp_in_rule(section: list[str]) -> ChangeSet:
|
||||
obj = InpRule(section)
|
||||
cs = ChangeSet({'operation' : API_UPDATE, 'type': 'rule', 'rule' : obj.rule})
|
||||
return cs
|
||||
|
||||
|
||||
def inp_out_rule(name: str) -> list[str]:
|
||||
obj = str(get_rule(name)['rule'])
|
||||
return obj.split('\n')
|
||||
|
||||
@@ -25,3 +25,19 @@ def set_title_cache(name: str, cs: ChangeSet) -> SqlChangeSet:
|
||||
|
||||
def set_title(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return execute_command(name, set_title_cache(name ,cs))
|
||||
|
||||
|
||||
class InpTitle:
|
||||
def __init__(self, section) -> None:
|
||||
self.value = '\n'.join(section)
|
||||
|
||||
|
||||
def inp_in_title(section: list[str]) -> ChangeSet:
|
||||
obj = InpTitle(section)
|
||||
cs = ChangeSet({'operation' : API_ADD, 'type': 'title', 'value' : obj.value})
|
||||
return cs
|
||||
|
||||
|
||||
def inp_out_title(name: str) -> list[str]:
|
||||
obj = str(get_title(name)['value'])
|
||||
return obj.split('\n')
|
||||
|
||||
@@ -65,3 +65,24 @@ def set_time_cache(name: str, cs: ChangeSet) -> SqlChangeSet:
|
||||
|
||||
def set_time(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return execute_command(name, set_time_cache(name, cs))
|
||||
|
||||
|
||||
def inp_in_time(section: list[str]) -> ChangeSet:
|
||||
cs = g_update_prefix | { 'type' : 'time' }
|
||||
for s in section:
|
||||
line = s.upper().strip()
|
||||
for key in get_time_schema('').keys():
|
||||
if line.startswith(key):
|
||||
value = line.removeprefix(key).strip()
|
||||
cs |= { key : value }
|
||||
return ChangeSet(cs)
|
||||
|
||||
|
||||
def inp_out_time(name: str) -> list[str]:
|
||||
lines = []
|
||||
objs = read_all(name, f"select * from times")
|
||||
for obj in objs:
|
||||
key = obj['key']
|
||||
value = obj['value']
|
||||
lines.append(f'{key} {value}')
|
||||
return lines
|
||||
|
||||
@@ -103,3 +103,24 @@ def set_option_cache(name: str, cs: ChangeSet) -> SqlChangeSet:
|
||||
|
||||
def set_option(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return execute_command(name, set_option_cache(name, cs))
|
||||
|
||||
|
||||
def inp_in_option(section: list[str]) -> ChangeSet:
|
||||
cs = g_update_prefix | { 'type' : 'option' }
|
||||
for s in section:
|
||||
line = s.upper().strip()
|
||||
for key in get_option_schema('').keys():
|
||||
if line.startswith(key):
|
||||
value = line.removeprefix(key).strip()
|
||||
cs |= { key : value }
|
||||
return ChangeSet(cs)
|
||||
|
||||
|
||||
def inp_out_option(name: str) -> list[str]:
|
||||
lines = []
|
||||
objs = read_all(name, f"select * from options")
|
||||
for obj in objs:
|
||||
key = obj['key']
|
||||
value = obj['value']
|
||||
lines.append(f'{key} {value}')
|
||||
return lines
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from .operation import read
|
||||
from .operation import *
|
||||
|
||||
|
||||
def _to_client_point(coord: str) -> dict[str, float]:
|
||||
@@ -9,3 +9,26 @@ def _to_client_point(coord: str) -> dict[str, float]:
|
||||
def get_node_coord(name: str, id: str) -> dict[str, float]:
|
||||
row = read(name, f"select * from coordinates where node = '{id}'")
|
||||
return _to_client_point(row['coord'])
|
||||
|
||||
# exception ! need merge to node change set !
|
||||
def inp_in_coord(section: list[str]) -> dict[str, dict[str, float]]:
|
||||
coords = {}
|
||||
for s in section:
|
||||
# skip comment
|
||||
if s.startswith(';'):
|
||||
continue
|
||||
tokens = s.split()
|
||||
coords[tokens[0]] = { 'x': tokens[1], 'y': tokens[2] }
|
||||
return coords
|
||||
|
||||
|
||||
def inp_out_junction(name: str) -> list[str]:
|
||||
lines = []
|
||||
objs = read_all(name, 'select * from coordinates')
|
||||
for obj in objs:
|
||||
node = obj['node']
|
||||
coord = _to_client_point(obj['coord'])
|
||||
x = coord['x']
|
||||
y = coord['y']
|
||||
lines.append(f'{node} {x} {y}')
|
||||
return lines
|
||||
|
||||
@@ -43,6 +43,21 @@ def set_vertex_cache(name: str, cs: ChangeSet) -> SqlChangeSet:
|
||||
return SqlChangeSet(redo_sql, undo_sql, redo_cs, undo_cs)
|
||||
|
||||
|
||||
def add_vertex_cache(name: str, cs: ChangeSet) -> SqlChangeSet:
|
||||
result = set_vertex_cache(name, cs)
|
||||
result.redo_cs |= g_add_prefix
|
||||
result.undo_cs |= g_delete_prefix
|
||||
return result
|
||||
|
||||
|
||||
def delete_vertex_cache(name: str, cs: ChangeSet) -> SqlChangeSet:
|
||||
cs.operations[0]['coords'] = []
|
||||
result = set_vertex_cache(name, cs)
|
||||
result.redo_cs |= g_delete_prefix
|
||||
result.undo_cs |= g_add_prefix
|
||||
return result
|
||||
|
||||
|
||||
def set_vertex(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
result = set_vertex_cache(name, cs)
|
||||
result.redo_cs |= g_update_prefix
|
||||
|
||||
@@ -118,3 +118,42 @@ def delete_junction_cache(name: str, cs: ChangeSet) -> SqlChangeSet:
|
||||
|
||||
def delete_junction(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return execute_command(name, delete_junction_cache(name, cs))
|
||||
|
||||
|
||||
class InpJunction:
|
||||
def __init__(self, line: str) -> None:
|
||||
tokens = line.split()
|
||||
|
||||
num = len(tokens)
|
||||
has_desc = tokens[-1].startswith(';')
|
||||
num_without_desc = (num - 1) if has_desc else num
|
||||
|
||||
self.id = str(tokens[0])
|
||||
self.elevation = float(tokens[1])
|
||||
self.demand = float(tokens[2]) if num_without_desc >= 3 else None
|
||||
self.pattern = str(tokens[3]) if num_without_desc >= 4 else None
|
||||
self.desc = str(tokens[-1]) if has_desc else None
|
||||
|
||||
|
||||
def inp_in_junction(section: list[str]) -> ChangeSet:
|
||||
cs = ChangeSet()
|
||||
for s in section:
|
||||
# skip comment
|
||||
if s.startswith(';'):
|
||||
continue
|
||||
obj = InpJunction(s)
|
||||
cs.append({'operation': API_ADD, 'type': 'junction', 'id': obj.id, 'elevation': obj.elevation, 'demand': obj.demand, 'pattern': obj.pattern})
|
||||
return cs
|
||||
|
||||
|
||||
def inp_out_junction(name: str) -> list[str]:
|
||||
lines = []
|
||||
objs = read_all(name, 'select * from junctions')
|
||||
for obj in objs:
|
||||
id = obj['id']
|
||||
elev = obj['elevation']
|
||||
demand = obj['demand'] if obj['demand'] != None else ''
|
||||
pattern = obj['pattern'] if obj['pattern'] != None else ''
|
||||
desc = ';'
|
||||
lines.append(f'{id} {elev} {demand} {pattern} {desc}')
|
||||
return lines
|
||||
|
||||
@@ -114,3 +114,40 @@ def delete_reservoir_cache(name: str, cs: ChangeSet) -> SqlChangeSet:
|
||||
|
||||
def delete_reservoir(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return execute_command(name, delete_reservoir_cache(name, cs))
|
||||
|
||||
|
||||
class InpReservoir:
|
||||
def __init__(self, line: str) -> None:
|
||||
tokens = line.split()
|
||||
|
||||
num = len(tokens)
|
||||
has_desc = tokens[-1].startswith(';')
|
||||
num_without_desc = (num - 1) if has_desc else num
|
||||
|
||||
self.id = str(tokens[0])
|
||||
self.head = float(tokens[1])
|
||||
self.pattern = str(tokens[2]) if num_without_desc >= 3 else None
|
||||
self.desc = str(tokens[-1]) if has_desc else None
|
||||
|
||||
|
||||
def inp_in_reservoir(section: list[str]) -> ChangeSet:
|
||||
cs = ChangeSet()
|
||||
for s in section:
|
||||
# skip comment
|
||||
if s.startswith(';'):
|
||||
continue
|
||||
obj = InpReservoir(s)
|
||||
cs.append({'operation': API_ADD, 'type': 'reservoir', 'id': obj.id, 'head': obj.head, 'pattern': obj.pattern})
|
||||
return cs
|
||||
|
||||
|
||||
def inp_out_reservoir(name: str) -> list[str]:
|
||||
lines = []
|
||||
objs = read_all(name, 'select * from reservoirs')
|
||||
for obj in objs:
|
||||
id = obj['id']
|
||||
head = obj['head']
|
||||
pattern = obj['pattern'] if obj['pattern'] != None else ''
|
||||
desc = ';'
|
||||
lines.append(f'{id} {head} {pattern} {desc}')
|
||||
return lines
|
||||
|
||||
@@ -142,3 +142,52 @@ def delete_tank_cache(name: str, cs: ChangeSet) -> SqlChangeSet:
|
||||
|
||||
def delete_tank(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return execute_command(name, delete_tank_cache(name, cs))
|
||||
|
||||
|
||||
class InpTank:
|
||||
def __init__(self, line: str) -> None:
|
||||
tokens = line.split()
|
||||
|
||||
num = len(tokens)
|
||||
has_desc = tokens[-1].startswith(';')
|
||||
num_without_desc = (num - 1) if has_desc else num
|
||||
|
||||
self.id = str(tokens[0])
|
||||
self.elevation = float(tokens[1])
|
||||
self.init_level = float(tokens[2])
|
||||
self.min_level = float(tokens[3])
|
||||
self.max_level = float(tokens[4])
|
||||
self.diameter = float(tokens[5])
|
||||
self.min_vol = float(tokens[6])
|
||||
self.vol_curve = str(tokens[7]) if num_without_desc >= 8 else None
|
||||
self.overflow = str(tokens[8]) if num_without_desc >= 9 else None
|
||||
self.desc = str(tokens[-1]) if has_desc else None
|
||||
|
||||
|
||||
def inp_in_tank(section: list[str]) -> ChangeSet:
|
||||
cs = ChangeSet()
|
||||
for s in section:
|
||||
# skip comment
|
||||
if s.startswith(';'):
|
||||
continue
|
||||
obj = InpTank(s)
|
||||
cs.append({'operation': API_ADD, 'type': 'tank', 'id': obj.id, 'elevation': obj.elevation, 'init_level': obj.init_level, 'min_level': obj.min_level, 'max_level': obj.max_level, 'diameter': obj.diameter, 'min_vol': obj.min_vol, 'vol_curve': obj.vol_curve, 'overflow': obj.overflow})
|
||||
return cs
|
||||
|
||||
|
||||
def inp_out_tank(name: str) -> list[str]:
|
||||
lines = []
|
||||
objs = read_all(name, 'select * from tanks')
|
||||
for obj in objs:
|
||||
id = obj['id']
|
||||
elevation = obj['elevation']
|
||||
init_level = obj['init_level']
|
||||
min_level = obj['min_level']
|
||||
max_level = obj['max_level']
|
||||
diameter = obj['diameter']
|
||||
min_vol = obj['min_vol']
|
||||
vol_curve = obj['vol_curve'] if obj['vol_curve'] != None else ''
|
||||
overflow = obj['overflow'] if obj['overflow'] != None else ''
|
||||
desc = ';'
|
||||
lines.append(f'{id} {elevation} {init_level} {min_level} {max_level} {diameter} {min_vol} {vol_curve} {overflow} {desc}')
|
||||
return lines
|
||||
|
||||
@@ -121,3 +121,51 @@ def delete_pipe_cache(name: str, cs: ChangeSet) -> SqlChangeSet:
|
||||
|
||||
def delete_pipe(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return execute_command(name, delete_pipe_cache(name, cs))
|
||||
|
||||
|
||||
class InpPipe:
|
||||
def __init__(self, line: str) -> None:
|
||||
tokens = line.split()
|
||||
|
||||
num = len(tokens)
|
||||
has_desc = tokens[-1].startswith(';')
|
||||
num_without_desc = (num - 1) if has_desc else num
|
||||
|
||||
self.id = str(tokens[0])
|
||||
self.node1 = str(tokens[1])
|
||||
self.node2 = str(tokens[2])
|
||||
self.length = float(tokens[3])
|
||||
self.diameter = float(tokens[4])
|
||||
self.roughness = float(tokens[5])
|
||||
self.minor_loss = float(tokens[6])
|
||||
# status is must-have, here fix input
|
||||
self.status = str(tokens[7]) if num_without_desc >= 8 else PIPE_STATUS_OPEN
|
||||
self.desc = str(tokens[-1]) if has_desc else None
|
||||
|
||||
|
||||
def inp_in_pipe(section: list[str]) -> ChangeSet:
|
||||
cs = ChangeSet()
|
||||
for s in section:
|
||||
# skip comment
|
||||
if s.startswith(';'):
|
||||
continue
|
||||
obj = InpPipe(s)
|
||||
cs.append({'operation': API_ADD, 'type': 'pipe', 'id': obj.id, 'node1': obj.node1, 'node2': obj.node2, 'length': obj.length, 'diameter': obj.diameter, 'roughness': obj.roughness, 'minor_loss': obj.minor_loss, 'status': obj.status})
|
||||
return cs
|
||||
|
||||
|
||||
def inp_out_pipe(name: str) -> list[str]:
|
||||
lines = []
|
||||
objs = read_all(name, 'select * from pipes')
|
||||
for obj in objs:
|
||||
id = obj['id']
|
||||
node1 = obj['node1']
|
||||
node2 = obj['node2']
|
||||
length = obj['length']
|
||||
diameter = obj['diameter']
|
||||
roughness = obj['roughness']
|
||||
minor_loss = obj['minor_loss']
|
||||
status = obj['vol_curve']
|
||||
desc = ';'
|
||||
lines.append(f'{id} {node1} {node2} {length} {diameter} {roughness} {minor_loss} {status} {desc}')
|
||||
return lines
|
||||
|
||||
@@ -112,3 +112,51 @@ def delete_pump_cache(name: str, cs: ChangeSet) -> SqlChangeSet:
|
||||
|
||||
def delete_pump(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return execute_command(name, delete_pump_cache(name, cs))
|
||||
|
||||
|
||||
class InpPump:
|
||||
def __init__(self, line: str) -> None:
|
||||
tokens = line.split()
|
||||
|
||||
num = len(tokens)
|
||||
has_desc = tokens[-1].startswith(';')
|
||||
num_without_desc = (num - 1) if has_desc else num
|
||||
|
||||
self.id = str(tokens[0])
|
||||
self.node1 = str(tokens[1])
|
||||
self.node2 = str(tokens[2])
|
||||
self.props = {}
|
||||
for i in range(3, num_without_desc, 2):
|
||||
self.props |= { tokens[i].lower(): tokens[i + 1] }
|
||||
self.power = float(self.props['power']) if 'power' in self.props else None
|
||||
self.head = str(self.props['head']) if 'head' in self.props else None
|
||||
self.speed = float(self.props['speed']) if 'speed' in self.props else None
|
||||
self.pattern = str(self.props['pattern']) if 'pattern' in self.props else None
|
||||
self.desc = str(tokens[-1]) if has_desc else None
|
||||
|
||||
|
||||
def inp_in_pump(section: list[str]) -> ChangeSet:
|
||||
cs = ChangeSet()
|
||||
for s in section:
|
||||
# skip comment
|
||||
if s.startswith(';'):
|
||||
continue
|
||||
obj = InpPump(s)
|
||||
cs.append({'operation': API_ADD, 'type': 'pump', 'id': obj.id, 'node1': obj.node1, 'node2': obj.node2, 'power': obj.power, 'head': obj.head, 'speed': obj.speed, 'pattern': obj.pattern})
|
||||
return cs
|
||||
|
||||
|
||||
def inp_out_pump(name: str) -> list[str]:
|
||||
lines = []
|
||||
objs = read_all(name, 'select * from pumps')
|
||||
for obj in objs:
|
||||
id = obj['id']
|
||||
node1 = obj['node1']
|
||||
node2 = obj['node2']
|
||||
power = f"POWER {obj['power']}" if obj['power'] != None else ''
|
||||
head = f"HEAD {obj['head']}" if obj['head'] != None else ''
|
||||
speed = f"SPEED {obj['speed']}" if obj['speed'] != None else ''
|
||||
pattern = f"PATTERN {obj['pattern']}" if obj['pattern'] != None else ''
|
||||
desc = ';'
|
||||
lines.append(f'{id} {node1} {node2} {power} {head} {speed} {pattern} {desc}')
|
||||
return lines
|
||||
|
||||
@@ -120,3 +120,48 @@ def delete_valve_cache(name: str, cs: ChangeSet) -> SqlChangeSet:
|
||||
|
||||
def delete_valve(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
return execute_command(name, delete_valve_cache(name, cs))
|
||||
|
||||
|
||||
class InpValve:
|
||||
def __init__(self, line: str) -> None:
|
||||
tokens = line.split()
|
||||
|
||||
num = len(tokens)
|
||||
has_desc = tokens[-1].startswith(';')
|
||||
num_without_desc = (num - 1) if has_desc else num
|
||||
|
||||
self.id = str(tokens[0])
|
||||
self.node1 = str(tokens[1])
|
||||
self.node2 = str(tokens[2])
|
||||
self.diameter = float(tokens[3])
|
||||
self.v_type = str(tokens[4])
|
||||
self.setting = float(tokens[5])
|
||||
self.minor_loss = float(tokens[6])
|
||||
self.desc = str(tokens[-1]) if has_desc else None
|
||||
|
||||
|
||||
def inp_in_valve(section: list[str]) -> ChangeSet:
|
||||
cs = ChangeSet()
|
||||
for s in section:
|
||||
# skip comment
|
||||
if s.startswith(';'):
|
||||
continue
|
||||
obj = InpValve(s)
|
||||
cs.append({'operation': API_ADD, 'type': 'valve', 'id': obj.id, 'node1': obj.node1, 'node2': obj.node2, 'diameter': obj.diameter, 'v_type': obj.v_type, 'setting': obj.setting, 'minor_loss': obj.minor_loss})
|
||||
return cs
|
||||
|
||||
|
||||
def inp_out_valve(name: str) -> list[str]:
|
||||
lines = []
|
||||
objs = read_all(name, 'select * from valves')
|
||||
for obj in objs:
|
||||
id = obj['id']
|
||||
node1 = obj['node1']
|
||||
node2 = obj['node2']
|
||||
diameter = obj['diameter']
|
||||
v_type = obj['type']
|
||||
setting = obj['setting']
|
||||
minor_loss = obj['minor_loss']
|
||||
desc = ';'
|
||||
lines.append(f'{id} {node1} {node2} {diameter} {v_type} {setting} {minor_loss} {desc}')
|
||||
return lines
|
||||
|
||||
@@ -84,3 +84,49 @@ def set_demand_cache(name: str, cs: ChangeSet) -> BatchSqlChangeSet:
|
||||
def set_demand(name: str, cs: ChangeSet) -> ChangeSet:
|
||||
css = set_demand_cache(name, cs)
|
||||
return execute_batch(name, css.redo_sql, css.undo_sql, css.redo_cs, css.undo_cs)
|
||||
|
||||
|
||||
class InpDemand:
|
||||
def __init__(self, line: str) -> None:
|
||||
tokens = line.split()
|
||||
|
||||
num = len(tokens)
|
||||
has_desc = tokens[-1].startswith(';')
|
||||
num_without_desc = (num - 1) if has_desc else num
|
||||
|
||||
self.junction = str(tokens[0])
|
||||
self.demand = float(tokens[1])
|
||||
self.pattern = str(tokens[2]) if num_without_desc >= 3 else None
|
||||
self.category = str(tokens[3]) if num_without_desc >= 4 else None
|
||||
|
||||
|
||||
def inp_in_demand(section: list[str]) -> ChangeSet:
|
||||
objs: dict[str, list[InpDemand]] = {}
|
||||
for s in section:
|
||||
# skip comment
|
||||
if s.startswith(';'):
|
||||
continue
|
||||
obj = InpDemand(s)
|
||||
if obj.junction not in objs:
|
||||
objs[obj.junction] = []
|
||||
objs[obj.junction].append(obj)
|
||||
|
||||
cs = ChangeSet()
|
||||
for junction, demands in objs.items():
|
||||
obj_cs = {'operation': API_UPDATE, 'type': 'demand', 'junction' : junction, 'demands' : []}
|
||||
for obj in demands:
|
||||
obj_cs['demands'].append({'demand': obj.demand, 'pattern' : obj.pattern, 'category': obj.category})
|
||||
cs.append(obj_cs)
|
||||
return cs
|
||||
|
||||
|
||||
def inp_out_demand(name: str) -> list[str]:
|
||||
lines = []
|
||||
objs = read_all(name, f"select * from demands order by _order")
|
||||
for obj in objs:
|
||||
junction = obj['junction']
|
||||
demand = obj['demand']
|
||||
patten = obj['patten'] if obj['patten'] != None else ''
|
||||
category = f";{obj['category']}" if obj['category'] != None else ';'
|
||||
lines.append(f'{junction} {demand} {patten} {category}')
|
||||
return lines
|
||||
|
||||
Reference in New Issue
Block a user