fewsvisualiser 1.0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- fewsvisualiser/__init__.py +11 -0
- fewsvisualiser/__main__.py +8 -0
- fewsvisualiser/analyse.py +61 -0
- fewsvisualiser/core/__init__.py +0 -0
- fewsvisualiser/core/dbconfigvis.py +401 -0
- fewsvisualiser/core/dblocset.py +79 -0
- fewsvisualiser/core/fewsparsers.py +543 -0
- fewsvisualiser/core/helpers.py +100 -0
- fewsvisualiser/core/locsetparser.py +76 -0
- fewsvisualiser/explore.py +123 -0
- fewsvisualiser/locset_analysis.py +43 -0
- fewsvisualiser-1.0.1.dist-info/METADATA +54 -0
- fewsvisualiser-1.0.1.dist-info/RECORD +14 -0
- fewsvisualiser-1.0.1.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
__version__ = "1.0.1"
|
|
2
|
+
|
|
3
|
+
from fewsvisualiser.analyse import analyse_config
|
|
4
|
+
from fewsvisualiser.explore import explore_config
|
|
5
|
+
from fewsvisualiser.locset_analysis import locset_analysis
|
|
6
|
+
|
|
7
|
+
__all__ = [
|
|
8
|
+
"analyse_config",
|
|
9
|
+
"explore_config",
|
|
10
|
+
"locset_analysis",
|
|
11
|
+
]
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
from fewsvisualiser.core.dbconfigvis import DbConfigVis
|
|
3
|
+
from fewsvisualiser.core.fewsparsers import Workflows_parser, TimeseriesSetParser, Modins_parser, Endpoint_parsers, CoefficientSet_parser, ModuleInstanceDescriptorParser, ModuleInstanceSetsParser
|
|
4
|
+
from fewsvisualiser.core.helpers import setup_logging, delete_file
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
#=======================================================================================
|
|
8
|
+
# MAIN PROGRAM
|
|
9
|
+
def analyse_config(croot, dbpath):
|
|
10
|
+
# Convert to Path objects
|
|
11
|
+
dbpath_obj = Path(dbpath)
|
|
12
|
+
|
|
13
|
+
# Extract the database name for the log file
|
|
14
|
+
db_name = dbpath_obj.stem
|
|
15
|
+
log_file = dbpath_obj.parent / f"{db_name}.log"
|
|
16
|
+
|
|
17
|
+
# Ensure we start with clean files
|
|
18
|
+
delete_file(log_file) # Clean log file
|
|
19
|
+
delete_file(dbpath) # Clean database file
|
|
20
|
+
|
|
21
|
+
# Setup logging
|
|
22
|
+
global logger
|
|
23
|
+
logger = setup_logging(__name__, str(log_file))
|
|
24
|
+
|
|
25
|
+
logger.info(f"root: {croot}")
|
|
26
|
+
logger.info(f"Log file: {log_file}")
|
|
27
|
+
logger.info(f"Starting with clean database: {dbpath}")
|
|
28
|
+
config_root = Path(croot)
|
|
29
|
+
|
|
30
|
+
db = DbConfigVis(dbpath, logger)
|
|
31
|
+
db.create_tables(logger)
|
|
32
|
+
|
|
33
|
+
# parsing workflow descriptors
|
|
34
|
+
Workflows_parser.parse_workflow_descriptors(config_root, db, logger)
|
|
35
|
+
# parsing workflow files
|
|
36
|
+
Workflows_parser.loop_workflows(config_root, db, logger)
|
|
37
|
+
|
|
38
|
+
#db.close(logger)
|
|
39
|
+
#exit(0)
|
|
40
|
+
#db.clear_tables(logger)
|
|
41
|
+
|
|
42
|
+
# parsing TimeSteps
|
|
43
|
+
TimeseriesSetParser.parse_timestep_id_file(config_root / "RegionConfigFiles/TimeSteps.xml", logger)
|
|
44
|
+
# parsing ModuleInstanceDescriptors
|
|
45
|
+
ModuleInstanceDescriptorParser.parse_moduleinstances_file(db, config_root, logger)
|
|
46
|
+
# parsing ModuleInstanceSets
|
|
47
|
+
ModuleInstanceSetsParser.parse_moduleinstancesets_file(db, config_root, logger)
|
|
48
|
+
# parsing filter files
|
|
49
|
+
Endpoint_parsers.parse_endpoint(db, config_root / "RegionConfigFiles", 'filters', logger)
|
|
50
|
+
# parsing displayGroups files
|
|
51
|
+
Endpoint_parsers.parse_endpoint(db, config_root / "SystemConfigFiles", 'displayGroups', logger)
|
|
52
|
+
# parsing gridDisplay files
|
|
53
|
+
Endpoint_parsers.parse_endpoint(db, config_root / "DisplayConfigFiles", 'gridDisplay', logger)
|
|
54
|
+
# parsing scadaDisplay (schematic displays) files
|
|
55
|
+
Endpoint_parsers.parse_endpoint(db, config_root / "DisplayConfigFiles", 'scadaDisplay', logger)
|
|
56
|
+
# parsing transformationCoefficientSets
|
|
57
|
+
CoefficientSet_parser.parse(config_root / "CoefficientSetsFiles", logger)
|
|
58
|
+
# parsing module instance files
|
|
59
|
+
Modins_parser.parse_modins(db, config_root, logger)
|
|
60
|
+
|
|
61
|
+
db.close(logger)
|
|
File without changes
|
|
@@ -0,0 +1,401 @@
|
|
|
1
|
+
import sqlite3
|
|
2
|
+
|
|
3
|
+
class DbConfigVis:
|
|
4
|
+
def __init__(self, dbpath, logger):
|
|
5
|
+
try:
|
|
6
|
+
self.con = sqlite3.connect(database=dbpath)
|
|
7
|
+
logger.info("Successfully connected to SQLite")
|
|
8
|
+
version = sqlite3.sqlite_version_info
|
|
9
|
+
logger.debug(f"SQLite Database Version is: {version}")
|
|
10
|
+
except sqlite3.Error as error:
|
|
11
|
+
logger.error("Error while connecting to SQLite", error)
|
|
12
|
+
exit(1)
|
|
13
|
+
|
|
14
|
+
def create_tables(self, logger):
|
|
15
|
+
cursor = self.con.cursor()
|
|
16
|
+
|
|
17
|
+
dll_props_sets_table = """CREATE TABLE props_sets (
|
|
18
|
+
id INTEGER NOT NULL,
|
|
19
|
+
key TEXT NOT NULL,
|
|
20
|
+
value TEXT NOT NULL,
|
|
21
|
+
CONSTRAINT PK_props_sets PRIMARY KEY (id, key))"""
|
|
22
|
+
cursor.execute(dll_props_sets_table)
|
|
23
|
+
logger.info("props_sets table created")
|
|
24
|
+
|
|
25
|
+
dll_call_stacks_table = """CREATE TABLE call_stacks (
|
|
26
|
+
id INTEGER NOT NULL,
|
|
27
|
+
wf_id TEXT NOT NULL,
|
|
28
|
+
description TEXT,
|
|
29
|
+
wffn TEXT NOT NULL,
|
|
30
|
+
parent_id INTEGER,
|
|
31
|
+
props_set_id INTEGER,
|
|
32
|
+
CONSTRAINT PK_call_stacks PRIMARY KEY (id),
|
|
33
|
+
FOREIGN KEY(props_set_id) REFERENCES props_sets(id),
|
|
34
|
+
FOREIGN KEY(parent_id) REFERENCES call_stacks(id))"""
|
|
35
|
+
cursor.execute(dll_call_stacks_table)
|
|
36
|
+
logger.info("call_stacks table created")
|
|
37
|
+
|
|
38
|
+
dll_modins_calls_table = """CREATE TABLE modins_calls (
|
|
39
|
+
id INTEGER NOT NULL,
|
|
40
|
+
call_stack_id INTEGER NOT NULL,
|
|
41
|
+
modins TEXT NOT NULL,
|
|
42
|
+
props_set_id INTEGER,
|
|
43
|
+
description TEXT,
|
|
44
|
+
CONSTRAINT PK_modins_calls PRIMARY KEY (id, call_stack_id),
|
|
45
|
+
FOREIGN KEY(props_set_id) REFERENCES props_sets(id),
|
|
46
|
+
FOREIGN KEY(call_stack_id) REFERENCES call_stacks(id))"""
|
|
47
|
+
cursor.execute(dll_modins_calls_table)
|
|
48
|
+
logger.info("modins_calls table created")
|
|
49
|
+
|
|
50
|
+
dll_timeseries_sets_table = """CREATE TABLE ts_sets (
|
|
51
|
+
id INTEGER NOT NULL,
|
|
52
|
+
modins TEXT NOT NULL,
|
|
53
|
+
vtype TEXT NOT NULL,
|
|
54
|
+
parid TEXT NOT NULL,
|
|
55
|
+
qualifiers TEXT,
|
|
56
|
+
tstype TEXT NOT NULL,
|
|
57
|
+
timess TEXT NOT NULL,
|
|
58
|
+
aggregation TEXT,
|
|
59
|
+
description TEXT,
|
|
60
|
+
CONSTRAINT PK_ts_sets PRIMARY KEY (id)
|
|
61
|
+
)"""
|
|
62
|
+
cursor.execute(dll_timeseries_sets_table)
|
|
63
|
+
logger.info("ts_sets table created")
|
|
64
|
+
|
|
65
|
+
dll_trafos_table = """CREATE TABLE trafos (
|
|
66
|
+
idx INTEGER NOT NULL,
|
|
67
|
+
mic_id INTEGER NOT NULL,
|
|
68
|
+
ord_nr INTEGER NOT NULL,
|
|
69
|
+
trafo_id TEXT NOT NULL,
|
|
70
|
+
description TEXT,
|
|
71
|
+
config_file TEXT NOT NULL,
|
|
72
|
+
CONSTRAINT PK_trafos PRIMARY KEY (idx),
|
|
73
|
+
UNIQUE(mic_id, ord_nr),
|
|
74
|
+
FOREIGN KEY(mic_id) REFERENCES modins_calls(id)
|
|
75
|
+
)"""
|
|
76
|
+
cursor.execute(dll_trafos_table)
|
|
77
|
+
logger.info("trafos table created")
|
|
78
|
+
|
|
79
|
+
dll_links_table = """CREATE TABLE links (
|
|
80
|
+
trafo_idx INTEGER NOT NULL,
|
|
81
|
+
tss_id INTEGER NOT NULL,
|
|
82
|
+
inout TEXT,
|
|
83
|
+
UNIQUE(trafo_idx, tss_id, inout),
|
|
84
|
+
FOREIGN KEY(trafo_idx) REFERENCES trafos(idx),
|
|
85
|
+
FOREIGN KEY(tss_id) REFERENCES ts_sets(id)
|
|
86
|
+
)"""
|
|
87
|
+
cursor.execute(dll_links_table)
|
|
88
|
+
logger.info("links table created")
|
|
89
|
+
|
|
90
|
+
dll_endpoints_table = """CREATE TABLE endpoints (
|
|
91
|
+
tss_id INTEGER NOT NULL,
|
|
92
|
+
description TEXT NOT NULL,
|
|
93
|
+
CONSTRAINT PK_endpoints PRIMARY KEY (tss_id, description),
|
|
94
|
+
FOREIGN KEY(tss_id) REFERENCES ts_sets(id)
|
|
95
|
+
)"""
|
|
96
|
+
cursor.execute(dll_endpoints_table)
|
|
97
|
+
logger.info("endpoints table created")
|
|
98
|
+
|
|
99
|
+
dll_moduleinstances_table = """CREATE TABLE moduleinstances (
|
|
100
|
+
modin_id TEXT NOT NULL,
|
|
101
|
+
name TEXT NOT NULL,
|
|
102
|
+
CONSTRAINT PK_moduleinstances PRIMARY KEY (modin_id))"""
|
|
103
|
+
cursor.execute(dll_moduleinstances_table)
|
|
104
|
+
logger.info("moduleinstances table created")
|
|
105
|
+
|
|
106
|
+
dll_moduleinstancesets_table = """CREATE TABLE moduleinstancesets (
|
|
107
|
+
set_id TEXT NOT NULL,
|
|
108
|
+
mid TEXT,
|
|
109
|
+
mip TEXT)"""
|
|
110
|
+
cursor.execute(dll_moduleinstancesets_table)
|
|
111
|
+
logger.info("moduleinstancesets table created")
|
|
112
|
+
|
|
113
|
+
self.con.commit()
|
|
114
|
+
logger.info("Database created")
|
|
115
|
+
|
|
116
|
+
def get_n_call_stacks(self):
|
|
117
|
+
row = self.con.execute("SELECT count(*) FROM call_stacks").fetchone()
|
|
118
|
+
return row[0]
|
|
119
|
+
|
|
120
|
+
def get_n_modins_calls(self):
|
|
121
|
+
row = self.con.execute("SELECT count(*) FROM modins_calls").fetchone()
|
|
122
|
+
return row[0]
|
|
123
|
+
|
|
124
|
+
def get_max_trafos_idx(self) -> int:
|
|
125
|
+
row = self.con.execute("SELECT MAX(idx) FROM trafos").fetchone()
|
|
126
|
+
return int(row[0]) if row[0] else 0
|
|
127
|
+
|
|
128
|
+
def get_max_call_stacks_id(self) -> int:
|
|
129
|
+
row = self.con.execute("SELECT MAX(id) FROM call_stacks").fetchone()
|
|
130
|
+
return int(row[0]) if row[0] else 0
|
|
131
|
+
|
|
132
|
+
def get_max_props_sets_id(self) -> int:
|
|
133
|
+
row = self.con.execute("SELECT MAX(id) FROM props_sets").fetchone()
|
|
134
|
+
return int(row[0]) if row[0] else 0
|
|
135
|
+
|
|
136
|
+
def get_max_modins_calls_id(self) -> int:
|
|
137
|
+
row = self.con.execute("SELECT MAX(id) FROM modins_calls").fetchone()
|
|
138
|
+
return int(row[0]) if row[0] else 0
|
|
139
|
+
|
|
140
|
+
def get_call_stack_from_wfid(self, wf_id, logger):
|
|
141
|
+
try:
|
|
142
|
+
cursor = self.con.cursor()
|
|
143
|
+
cs = self.con.execute("SELECT id, description, wffn, props_set_id FROM call_stacks WHERE wf_id =:wf_id", {"wf_id": wf_id}).fetchone()
|
|
144
|
+
except sqlite3.Error as error:
|
|
145
|
+
logger.error(error)
|
|
146
|
+
finally:
|
|
147
|
+
cursor.close()
|
|
148
|
+
return cs
|
|
149
|
+
|
|
150
|
+
def get_tss(self, tss_id, logger):
|
|
151
|
+
try:
|
|
152
|
+
return self.con.execute("SELECT * FROM ts_sets WHERE id =:id", {"id": tss_id}).fetchone()
|
|
153
|
+
except sqlite3.Error as error:
|
|
154
|
+
logger.error(error)
|
|
155
|
+
raise
|
|
156
|
+
|
|
157
|
+
def get_trafo_index(self, mic_id, ord_nr, trafo_id, trafo_description, config_file, logger):
|
|
158
|
+
try:
|
|
159
|
+
cursor = self.con.cursor()
|
|
160
|
+
# find trafo_id
|
|
161
|
+
trafo_row = self.con.execute("SELECT idx FROM trafos WHERE mic_id=:mic_id AND ord_nr=:ord_nr", {"mic_id": mic_id, "ord_nr": ord_nr}).fetchone()
|
|
162
|
+
if trafo_row is None:
|
|
163
|
+
idx = self.get_max_trafos_idx() + 1
|
|
164
|
+
insert_statement = """INSERT INTO 'trafos' ('idx','mic_id','ord_nr','trafo_id','description','config_file') VALUES (?, ?, ?, ?, ?, ?);"""
|
|
165
|
+
cursor.execute(insert_statement, (idx, mic_id, ord_nr, trafo_id, trafo_description, config_file))
|
|
166
|
+
self.con.commit()
|
|
167
|
+
else:
|
|
168
|
+
idx = trafo_row[0]
|
|
169
|
+
except sqlite3.Error as error:
|
|
170
|
+
logger.error(error)
|
|
171
|
+
idx = None
|
|
172
|
+
raise
|
|
173
|
+
finally:
|
|
174
|
+
cursor.close()
|
|
175
|
+
return idx
|
|
176
|
+
|
|
177
|
+
def add_inoutput(self, mic_id, ord_nr, trafo_id, trafo_description, config_file, tss_id, direction, logger):
|
|
178
|
+
trafo_idx = self.get_trafo_index(mic_id, ord_nr, trafo_id, trafo_description, config_file, logger)
|
|
179
|
+
try:
|
|
180
|
+
cursor = self.con.cursor()
|
|
181
|
+
insert_statement = """INSERT INTO 'links' ('trafo_idx','tss_id','inout') VALUES (?, ?, ?);"""
|
|
182
|
+
cursor.execute(insert_statement, (trafo_idx, tss_id, direction))
|
|
183
|
+
self.con.commit()
|
|
184
|
+
except sqlite3.IntegrityError as error:
|
|
185
|
+
pass
|
|
186
|
+
except sqlite3.Error as error:
|
|
187
|
+
logger.warn(error)
|
|
188
|
+
raise
|
|
189
|
+
finally:
|
|
190
|
+
cursor.close()
|
|
191
|
+
|
|
192
|
+
def add_input(self, mic_id, ord_nr, trafo_id, description, config_file, tss_id, logger):
|
|
193
|
+
self.add_inoutput(mic_id, ord_nr, trafo_id, description, config_file, tss_id, 'in', logger)
|
|
194
|
+
|
|
195
|
+
def add_output(self, mic_id, ord_nr, trafo_id, description, config_file, tss_id, logger):
|
|
196
|
+
self.add_inoutput(mic_id, ord_nr, trafo_id, description, config_file, tss_id, 'out', logger)
|
|
197
|
+
|
|
198
|
+
def insert_props_set(self, properties_set, logger) -> int:
|
|
199
|
+
if not properties_set:
|
|
200
|
+
return None
|
|
201
|
+
new_ps_id = self.get_max_props_sets_id() + 1
|
|
202
|
+
try:
|
|
203
|
+
cursor = self.con.cursor()
|
|
204
|
+
for key, value in properties_set.items():
|
|
205
|
+
data = (new_ps_id, key, value)
|
|
206
|
+
try:
|
|
207
|
+
insert_statement = """INSERT INTO 'props_sets' ('id','key','value') VALUES (?, ?, ?);"""
|
|
208
|
+
logger.debug("INSERT INTO props_sets: {}".format(data))
|
|
209
|
+
cursor.execute(insert_statement, data)
|
|
210
|
+
except sqlite3.IntegrityError as error:
|
|
211
|
+
logger.error(error)
|
|
212
|
+
logger.warn("property overwritten: {}: {}".format(key, value))
|
|
213
|
+
update_statement = """UPDATE 'props_sets' SET value = ? WHERE id = ? AND key = ?"""
|
|
214
|
+
cursor.execute(update_statement, (value, new_ps_id, key))
|
|
215
|
+
self.con.commit()
|
|
216
|
+
finally:
|
|
217
|
+
cursor.close()
|
|
218
|
+
return new_ps_id
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
def add_call_stack(self, wfid, desc, wffn, parent, psid) -> int:
|
|
222
|
+
try:
|
|
223
|
+
cursor = self.con.cursor()
|
|
224
|
+
ccs_id = self.get_max_call_stacks_id() + 1
|
|
225
|
+
# create a new call stack
|
|
226
|
+
data = (ccs_id, wfid, desc, wffn, parent, psid)
|
|
227
|
+
insert_statement = """INSERT INTO 'call_stacks' ('id','wf_id','description','wffn','parent_id','props_set_id') VALUES (?,?,?,?,?,?);"""
|
|
228
|
+
cursor.execute(insert_statement, data)
|
|
229
|
+
self.con.commit()
|
|
230
|
+
finally:
|
|
231
|
+
cursor.close()
|
|
232
|
+
return ccs_id
|
|
233
|
+
|
|
234
|
+
def add_modins_calls(self, modfn, csid, psid, desc):
|
|
235
|
+
try:
|
|
236
|
+
cursor = self.con.cursor()
|
|
237
|
+
mic_id = self.get_max_modins_calls_id() + 1
|
|
238
|
+
data = (mic_id, csid, modfn, psid, desc)
|
|
239
|
+
insert_statement = """INSERT INTO 'modins_calls' ('id', 'call_stack_id', 'modins', 'props_set_id', 'description') VALUES (?, ?, ?, ?, ?);"""
|
|
240
|
+
cursor.execute(insert_statement, data)
|
|
241
|
+
self.con.commit()
|
|
242
|
+
finally:
|
|
243
|
+
cursor.close()
|
|
244
|
+
|
|
245
|
+
def wfs_insert(self, wf_id, wf_desc, wf_fn, cps_id):
|
|
246
|
+
try:
|
|
247
|
+
cursor = self.con.cursor()
|
|
248
|
+
data = (wf_id, wf_desc, wf_fn, cps_id)
|
|
249
|
+
insert_statement = """INSERT INTO 'wfs' ('id','description','filename', 'props_set_id') VALUES (?, ?, ?, ?);"""
|
|
250
|
+
cursor.execute(insert_statement, data)
|
|
251
|
+
self.con.commit()
|
|
252
|
+
finally:
|
|
253
|
+
cursor.close()
|
|
254
|
+
|
|
255
|
+
def mid_insert(self, mi_id, mi_name, logger):
|
|
256
|
+
try:
|
|
257
|
+
cursor = self.con.cursor()
|
|
258
|
+
data = (mi_id, mi_name)
|
|
259
|
+
insert_statement = """INSERT INTO 'moduleinstances' ('modin_id', 'name') VALUES (?, ?);"""
|
|
260
|
+
cursor.execute(insert_statement, data)
|
|
261
|
+
self.con.commit()
|
|
262
|
+
except sqlite3.IntegrityError('UNIQUE constraint failed: moduleinstances.modin_id') as error:
|
|
263
|
+
logger.error(error)
|
|
264
|
+
logger.warning("Module instance already exists: {}: {}".format(mi_id, mi_name))
|
|
265
|
+
logger.error('Check for duplicate modules instances in RegionConfigFiles/ModuleInstanceDescriptors.xml')
|
|
266
|
+
finally:
|
|
267
|
+
cursor.close()
|
|
268
|
+
|
|
269
|
+
def miset_insert(self, mis_id, mid, mip):
|
|
270
|
+
try:
|
|
271
|
+
cursor = self.con.cursor()
|
|
272
|
+
data = (mis_id, mid, mip)
|
|
273
|
+
insert_statement = """INSERT INTO 'moduleinstancesets' ('set_id', 'mid', 'mip') VALUES (?, ?, ?);"""
|
|
274
|
+
cursor.execute(insert_statement, data)
|
|
275
|
+
self.con.commit()
|
|
276
|
+
finally:
|
|
277
|
+
cursor.close()
|
|
278
|
+
|
|
279
|
+
def list_wfs(self):
|
|
280
|
+
return self.con.execute("SELECT id, wf_id, wffn, props_set_id FROM call_stacks").fetchall()
|
|
281
|
+
|
|
282
|
+
def list_modins(self):
|
|
283
|
+
return self.con.execute("SELECT id, modins, call_stack_id, props_set_id FROM modins_calls ORDER BY modins ASC").fetchall()
|
|
284
|
+
|
|
285
|
+
def get_props_set(self, id, logger):
|
|
286
|
+
try:
|
|
287
|
+
props = {}
|
|
288
|
+
[props.update({row[0]: row[1]}) for row in self.con.execute("SELECT key, value FROM props_sets WHERE id =:id", {"id": id}).fetchall()]
|
|
289
|
+
return props
|
|
290
|
+
except sqlite3.Error as error:
|
|
291
|
+
logger.error("Error get_props_set: ", error)
|
|
292
|
+
raise
|
|
293
|
+
|
|
294
|
+
def add_tts(self, tss, logger):
|
|
295
|
+
try:
|
|
296
|
+
# tss_id
|
|
297
|
+
tss_id_row = self.con.execute("SELECT MAX(id) FROM ts_sets").fetchone()
|
|
298
|
+
if tss_id_row[0] is None:
|
|
299
|
+
tss_id = 1
|
|
300
|
+
else:
|
|
301
|
+
tss_id = int(tss_id_row[0]) + 1
|
|
302
|
+
|
|
303
|
+
cursor = self.con.cursor()
|
|
304
|
+
data = (tss_id, ) + tss
|
|
305
|
+
insert_statement = """INSERT INTO 'ts_sets' ('id', 'modins', 'vtype', 'parid', 'qualifiers', 'tstype', 'timess', 'aggregation', 'description') VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);"""
|
|
306
|
+
cursor.execute(insert_statement, data)
|
|
307
|
+
self.con.commit()
|
|
308
|
+
except sqlite3.Error as error:
|
|
309
|
+
logger.error("Error add_tts: ", error)
|
|
310
|
+
finally:
|
|
311
|
+
cursor.close()
|
|
312
|
+
return tss_id
|
|
313
|
+
|
|
314
|
+
def get_tss_id(self, tss, logger):
|
|
315
|
+
try:
|
|
316
|
+
select_statement = "SELECT id, description FROM ts_sets WHERE modins = ? AND vtype = ? AND parid = ? AND qualifiers = ? AND tstype = ? AND timess = ? AND aggregation = ?"
|
|
317
|
+
# the eighth elem is the description, which is optional
|
|
318
|
+
desc_id = 7
|
|
319
|
+
row = self.con.execute(select_statement, tss[0:desc_id]).fetchone()
|
|
320
|
+
if row is None:
|
|
321
|
+
tss_id = self.add_tts(tss, logger)
|
|
322
|
+
else:
|
|
323
|
+
tss_id = row[0]
|
|
324
|
+
# append description if it exists
|
|
325
|
+
if tss[7]:
|
|
326
|
+
if not tss[desc_id].lower() in row[1].lower():
|
|
327
|
+
# update the description
|
|
328
|
+
logger.info(f"Updating description for tss_id {tss_id}")
|
|
329
|
+
if row[1]:
|
|
330
|
+
new_description = row[1] + "; " + tss[desc_id].lower()
|
|
331
|
+
else:
|
|
332
|
+
new_description = tss[desc_id].lower()
|
|
333
|
+
update_statement = "UPDATE ts_sets SET description = ? WHERE id = ?"
|
|
334
|
+
self.con.execute(update_statement, (new_description, tss_id))
|
|
335
|
+
self.con.commit()
|
|
336
|
+
except sqlite3.Error as error:
|
|
337
|
+
logger.error("Error get_tss_id: ", error)
|
|
338
|
+
raise
|
|
339
|
+
return tss_id
|
|
340
|
+
|
|
341
|
+
def add_endpoint(self, tss_id, desc, logger):
|
|
342
|
+
try:
|
|
343
|
+
cursor = self.con.cursor()
|
|
344
|
+
insert_statement = """INSERT INTO 'endpoints' ('tss_id','description') VALUES (?, ?);"""
|
|
345
|
+
cursor.execute(insert_statement, (tss_id, desc))
|
|
346
|
+
self.con.commit()
|
|
347
|
+
except sqlite3.IntegrityError as error:
|
|
348
|
+
pass
|
|
349
|
+
except sqlite3.Error as error:
|
|
350
|
+
logger.error("Error add_endpoint: ", error)
|
|
351
|
+
raise
|
|
352
|
+
finally:
|
|
353
|
+
cursor.close()
|
|
354
|
+
|
|
355
|
+
def clear_tables(self, logger):
|
|
356
|
+
try:
|
|
357
|
+
cursor = self.con.cursor()
|
|
358
|
+
cursor.execute("DELETE FROM endpoints")
|
|
359
|
+
cursor.execute("DELETE FROM links")
|
|
360
|
+
cursor.execute("DELETE FROM trafos")
|
|
361
|
+
cursor.execute("DELETE FROM ts_sets")
|
|
362
|
+
self.con.commit()
|
|
363
|
+
except sqlite3.Error as error:
|
|
364
|
+
logger.error("Error clear_tables: ", error)
|
|
365
|
+
raise
|
|
366
|
+
finally:
|
|
367
|
+
cursor.close()
|
|
368
|
+
|
|
369
|
+
def close(self, logger):
|
|
370
|
+
try:
|
|
371
|
+
self.con.close()
|
|
372
|
+
logger.info("Db closed")
|
|
373
|
+
except sqlite3.Error as error:
|
|
374
|
+
logger.error("Error while closing to sqlite: ", error)
|
|
375
|
+
raise
|
|
376
|
+
|
|
377
|
+
def get_links_by_tss(self, tss_id, direction, logger):
|
|
378
|
+
try:
|
|
379
|
+
links = set()
|
|
380
|
+
data = {"tss_id": tss_id, "inout": direction}
|
|
381
|
+
[links.add(row) for row in self.con.execute("SELECT * FROM links WHERE tss_id =:tss_id AND inout =:inout", data).fetchall()]
|
|
382
|
+
return links
|
|
383
|
+
except sqlite3.Error as error:
|
|
384
|
+
logger.error(error)
|
|
385
|
+
raise
|
|
386
|
+
|
|
387
|
+
def get_links_by_trafo(self, trafo_id, direction, logger):
|
|
388
|
+
try:
|
|
389
|
+
links = set()
|
|
390
|
+
data = {"trafo_id": trafo_id, "inout": direction}
|
|
391
|
+
[links.add(row) for row in self.con.execute("SELECT * FROM links WHERE trafo_id =:trafo_id AND inout =:inout", data).fetchall()]
|
|
392
|
+
return links
|
|
393
|
+
except sqlite3.Error as error:
|
|
394
|
+
logger.error(error)
|
|
395
|
+
raise
|
|
396
|
+
|
|
397
|
+
def general_query(self, query, logger):
|
|
398
|
+
try:
|
|
399
|
+
return self.con.execute(query).fetchall()
|
|
400
|
+
except sqlite3.Error as error:
|
|
401
|
+
logger.error(error)
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import sqlite3
|
|
2
|
+
|
|
3
|
+
class DbCLocSet:
|
|
4
|
+
def __init__(self, dbpath, logger):
|
|
5
|
+
try:
|
|
6
|
+
self.con = sqlite3.connect(database=dbpath)
|
|
7
|
+
logger.info("Successfully connected to SQLite")
|
|
8
|
+
version = sqlite3.sqlite_version_info
|
|
9
|
+
logger.debug(f"SQLite Database Version is: {version}")
|
|
10
|
+
except sqlite3.Error as error:
|
|
11
|
+
logger.error("Error while connecting to SQLite", error)
|
|
12
|
+
exit(1)
|
|
13
|
+
|
|
14
|
+
def create_tables(self, logger):
|
|
15
|
+
cursor = self.con.cursor()
|
|
16
|
+
|
|
17
|
+
dll_locsets_table = """CREATE TABLE locsets (
|
|
18
|
+
id TEXT NOT NULL,
|
|
19
|
+
name TEXT NOT NULL,
|
|
20
|
+
source TEXT NOT NULL,
|
|
21
|
+
CONSTRAINT PK_locsets_id PRIMARY KEY (id))"""
|
|
22
|
+
cursor.execute(dll_locsets_table)
|
|
23
|
+
logger.info("locsets table created")
|
|
24
|
+
|
|
25
|
+
dll_locsets_relations_table = """CREATE TABLE locsets_relations (
|
|
26
|
+
id TEXT NOT NULL,
|
|
27
|
+
parent_id TEXT,
|
|
28
|
+
FOREIGN KEY(parent_id) REFERENCES locsets(id))"""
|
|
29
|
+
cursor.execute(dll_locsets_relations_table)
|
|
30
|
+
logger.info("locsets_relations table created")
|
|
31
|
+
|
|
32
|
+
dll_attributes_table = """CREATE TABLE attributes (
|
|
33
|
+
id TEXT NOT NULL,
|
|
34
|
+
locset_id TEXT NOT NULL,
|
|
35
|
+
name TEXT,
|
|
36
|
+
source TEXT NOT NULL,
|
|
37
|
+
field TEXT NOT NULL,
|
|
38
|
+
FOREIGN KEY(locset_id) REFERENCES locsets(id))"""
|
|
39
|
+
cursor.execute(dll_attributes_table)
|
|
40
|
+
logger.info("attributes table created")
|
|
41
|
+
self.con.commit()
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def insert_locset(self, locset, logger):
|
|
45
|
+
cursor = self.con.cursor()
|
|
46
|
+
try:
|
|
47
|
+
cursor.execute("INSERT INTO locsets (id, name, source) VALUES (?, ?, ?)",
|
|
48
|
+
(locset['id'], locset['name'], locset.get('source', '')))
|
|
49
|
+
self.con.commit()
|
|
50
|
+
logger.info(f"Inserted locset: {locset['id']}")
|
|
51
|
+
except sqlite3.Error as error:
|
|
52
|
+
logger.error(f"Error inserting locset {locset['id']}: {error}")
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def insert_locset_relation(self, locset_id, parent_id, logger):
|
|
56
|
+
cursor = self.con.cursor()
|
|
57
|
+
try:
|
|
58
|
+
cursor.execute("INSERT INTO locsets_relations (id, parent_id) VALUES (?, ?)",
|
|
59
|
+
(locset_id, parent_id))
|
|
60
|
+
self.con.commit()
|
|
61
|
+
logger.info(f"Inserted locset relation: {locset_id} -> {parent_id}")
|
|
62
|
+
except sqlite3.Error as error:
|
|
63
|
+
logger.error(f"Error inserting locset relation {locset_id} -> {parent_id}: {error}")
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def general_query(self, query, logger):
|
|
67
|
+
try:
|
|
68
|
+
return self.con.execute(query).fetchall()
|
|
69
|
+
except sqlite3.Error as error:
|
|
70
|
+
logger.error(error)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def close(self, logger):
|
|
74
|
+
try:
|
|
75
|
+
self.con.close()
|
|
76
|
+
logger.info("Db closed")
|
|
77
|
+
except sqlite3.Error as error:
|
|
78
|
+
logger.error("Error while closing to sqlite: ", error)
|
|
79
|
+
raise
|