From 6061c6380990bdab64f397fdb9848fb8dd67a0ac Mon Sep 17 00:00:00 2001 From: ispyisail Date: Sun, 2 Aug 2026 12:43:21 +1200 Subject: [PATCH] Add wiring_list_view: from-to wiring list over the conductor tables Slice 3 of discussion #503, on top of slice 2 (#628). One row per conductor, each endpoint resolved to its element label and terminal name -- the `F1:4 -> M200:U1` shape from the original prototype. The view deviates from the SQL sketched in the discussion in two ways, both because the sketched version silently loses wires: - **No join to the `element` table.** A terminal row already carries its `element_uuid`, so joining `element` back just to read the same uuid adds nothing. Worse, it filters: `populateElementTable()` only inserts elements matching `Simple|Terminal|Master|Thumbnail`, so `Slave` elements (relay contacts and the like -- extremely common at the end of a wire) and report elements are simply absent from that table after a project load, and an inner join through it drops their conductors. - **`element_info` is LEFT joined** for the same reason. A wire whose endpoint element has no info row still belongs in a wiring list; it comes back with an empty label rather than vanishing. Losing a wire from a wiring list is a worse failure than showing one with a blank end. Note this only bites after a save/reload. The incremental `addElement()` path does not apply the type filter, so a slave element placed live is present in `element`/`element_info` and an inner join looks fine -- it is the bulk repopulate on project load that drops it. Testing only the live-editing path would have missed this entirely. Measured, comparing this view against an inner-join-through-element variant built from the same tables in the same session: | project | conductors | wiring_list_view | inner-join variant | |---|---|---|---| | Polonez MR'89 wiring diagram | 280 | 280 | 280 | | two slave contacts, after save+reload | 1 | **1** | **0** | Polonez happens to have no slave elements at conductor ends, so both agree there and the problem is invisible. The second case is the minimal reproduction: place two "Simple contact" elements (`link_type="slave"`) so autoconnect wires them, save, reload -- the sketched view returns zero rows for a project that plainly has a wire in it. Acceptance criterion held throughout: `wiring_list_view` row count equals `conductor` row count, i.e. the view itself drops nothing. Conductors already excluded upstream (legacy terminals without uuids, see #628) stay excluded; that remains the only thing missing from the list, and is what slice 4 should surface a count for. --- sources/dataBase/projectdatabase.cpp | 51 ++++++++++++++++++++++++++++ sources/dataBase/projectdatabase.h | 1 + 2 files changed, 52 insertions(+) diff --git a/sources/dataBase/projectdatabase.cpp b/sources/dataBase/projectdatabase.cpp index 37bb3d2e6..ff48bfd80 100644 --- a/sources/dataBase/projectdatabase.cpp +++ b/sources/dataBase/projectdatabase.cpp @@ -505,6 +505,7 @@ bool projectDataBase::createDataBase() createElementNomenclatureView(); createSummaryView(); + createWiringListView(); prepareQuery(); updateDB(); return true; @@ -622,6 +623,56 @@ void projectDataBase::createSummaryView() } } +/** + @brief projectDataBase::createWiringListView + A from-to wiring list: one row per conductor, each endpoint resolved to + its element label and terminal name. + + Two deliberate differences from an ordinary inner-join view like + element_nomenclature_view: + + - No join to the element table. A terminal row already carries its + element_uuid, so joining element back just to read the same uuid adds + nothing -- and would actively drop rows, because populateElementTable() + only inserts elements matching Simple|Terminal|Master|Thumbnail. Slave + elements (relay contacts and the like, extremely common at the end of a + wire) and report elements are absent from that table after a project + load, so an inner join through it silently loses their conductors. + - element_info is LEFT joined for the same reason. A wire whose endpoint + element carries no info row still belongs in a wiring list; it comes + back with an empty label rather than vanishing. Losing a wire from a + wiring list is a worse failure than showing one with a blank end. + + The result is that this view returns exactly as many rows as the + conductor table holds -- what is already excluded upstream (conductors + on legacy terminals without uuids) stays excluded, and nothing new is + dropped here. +*/ +void projectDataBase::createWiringListView() +{ + QString create_view ("CREATE VIEW wiring_list_view AS SELECT " + "c.uuid AS conductor_uuid," + "c.text AS wire_number," + "t1.element_uuid AS from_element_uuid," + "ei1.label AS from_element_label," + "t1.name AS from_terminal," + "t2.element_uuid AS to_element_uuid," + "ei2.label AS to_element_label," + "t2.name AS to_terminal," + "d.pos AS diagram_position" + " FROM conductor c" + " JOIN terminal t1 ON c.terminal1_uuid = t1.uuid AND c.terminal1_element_uuid = t1.element_uuid" + " JOIN terminal t2 ON c.terminal2_uuid = t2.uuid AND c.terminal2_element_uuid = t2.element_uuid" + " LEFT JOIN element_info ei1 ON t1.element_uuid = ei1.element_uuid" + " LEFT JOIN element_info ei2 ON t2.element_uuid = ei2.element_uuid" + " JOIN diagram d ON c.diagram_uuid = d.uuid"); + + QSqlQuery query(m_data_base); + if (!query.exec(create_view)) { + qDebug() << query.lastError(); + } +} + void projectDataBase::populateDiagramTable() { QSqlQuery query_(m_data_base); diff --git a/sources/dataBase/projectdatabase.h b/sources/dataBase/projectdatabase.h index cddf53468..65ca17950 100644 --- a/sources/dataBase/projectdatabase.h +++ b/sources/dataBase/projectdatabase.h @@ -77,6 +77,7 @@ class projectDataBase : public QObject bool createDataBase(); void createElementNomenclatureView(); void createSummaryView(); + void createWiringListView(); void populateDiagramTable(); void populateElementTable(); void populateElementInfoTable();