mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-08-22 16:44:14 +02:00
43da912aad
Slice 2 of discussion #503 (from-to wiring list built on projectDataBase), building on the conductor uuid from slice 1 (#625). Pure plumbing: two new additive tables plus their populate/add/remove hooks. No view, no UI, no visible behavior change yet -- the wiring-list view is slice 3. Follows the existing shape of the class throughout: same table/column naming, same prepared-statement idiom in prepareQuery(), same bind/exec/qDebug-lastError error handling, same DELETE-then-loop populate pattern. - `terminal (uuid, element_uuid, name)` and `conductor (uuid, diagram_uuid, terminal1_uuid, terminal1_element_uuid, terminal2_uuid, terminal2_element_uuid, text)` created alongside the existing tables in createDataBase(). - populateConductorTable() added as a fifth populate* call in updateDB(). Terminal population is folded into it, since a terminal only matters here in the context of a conductor referencing it. - addConductor()/removeConductor() hooked into the already-existing Conductor::Type branch of Diagram::addItem()/removeItem(), mirroring the Element::Type branch directly above. Two things the original schema sketch in the discussion got wrong, found by testing rather than inspection: 1. Terminal::uuid() is NOT unique per placed terminal. It is the terminal-position id baked into the catalog .elmt definition ("the top terminal"), so every placed instance of the same catalog element shares it. A terminal instance is only uniquely identified by (uuid, element_uuid) together, so that pair is the terminal table's primary key and the conductor table carries both halves for each endpoint. With uuid alone as PK, the second placed instance of any element silently lost its terminals to the INSERT OR IGNORE. 2. Conductors whose terminals predate terminal uuids are omitted rather than given a fabricated identity, as agreed in the discussion. This turns out to matter far more than expected in practice -- see below. Testing (all live, in the running app): - Incremental add: fresh project, two vertically aligned contacts placed so autoconnect creates a conductor -> 2 terminals, 1 conductor. - Incremental remove: deleting that conductor -> conductor count 1 -> 0. - Undo: ctrl+Z after the delete -> back to 1, no duplicate-primary-key error (the same Conductor object keeps its uuid). - Bulk populate: examples/weneedpolonez-Polonez_MR89_wiring_diagram.qet (366 conductors) -> 478 terminals, 280 conductors; the 86 conductors touching legacy terminals correctly omitted. - Join correctness: conductor -> terminal (composite key) -> element_info resolves real from-to rows with real element labels. - Legacy-only project: examples/industrial.qet has 1794 terminals and *zero* terminal uuids, so all 671 of its conductors are omitted. Loads and renders fine, no crash, no spurious rows -- but worth stating plainly that a from-to wiring list for that project would be empty today. This is a property of the element catalog definitions, not of the project file, and is the strongest argument for surfacing an "N conductors excluded" count to the user when the view lands. - No SQL errors logged in any of the above. Known limitation, consistent with existing behavior: removeDiagram() does not cascade-delete the conductor rows of that diagram, exactly as it already does not cascade to element/element_info. A full updateDB() rebuild clears them, and the future wiring-list view INNER JOINs from conductor, so orphan terminal rows never surface.
112 lines
3.1 KiB
C++
112 lines
3.1 KiB
C++
/*
|
|
Copyright 2006-2026 QElectroTech Team
|
|
This file is part of QElectroTech.
|
|
|
|
QElectroTech is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
QElectroTech is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
#ifndef PROJECTDATABASE_H
|
|
#define PROJECTDATABASE_H
|
|
|
|
#include <QObject>
|
|
#include <QSqlDatabase>
|
|
#include <QSqlQuery>
|
|
#include <QPointer>
|
|
#include <QFileDialog>
|
|
|
|
class Element;
|
|
class QETProject;
|
|
class Diagram;
|
|
class Conductor;
|
|
class Terminal;
|
|
class sqlite3;
|
|
|
|
/**
|
|
@brief The projectDataBase class
|
|
This class wraps a sqlite data base where you can find several things
|
|
about the content of a project.
|
|
*
|
|
@note this class is still in development.
|
|
*/
|
|
class projectDataBase : public QObject
|
|
{
|
|
Q_OBJECT
|
|
|
|
public:
|
|
projectDataBase(QETProject *project, QObject *parent = nullptr);
|
|
virtual ~projectDataBase() override;
|
|
|
|
void updateDB();
|
|
QETProject *project() const;
|
|
QSqlQuery newQuery(const QString &query = QString());
|
|
|
|
void addElement (Element *element);
|
|
void removeElement (Element *element);
|
|
void elementInfoChanged (Element *element);
|
|
void elementInfoChanged (QList<Element *> elements);
|
|
|
|
void addDiagram (Diagram *diagram);
|
|
void removeDiagram (Diagram *diagram);
|
|
void diagramInfoChanged (Diagram *diagram);
|
|
void diagramOrderChanged();
|
|
|
|
void addConductor (Conductor *conductor);
|
|
void removeConductor (Conductor *conductor);
|
|
|
|
signals:
|
|
void dataBaseUpdated();
|
|
|
|
private:
|
|
bool createDataBase();
|
|
void createElementNomenclatureView();
|
|
void createSummaryView();
|
|
void populateDiagramTable();
|
|
void populateElementTable();
|
|
void populateElementInfoTable();
|
|
void populateDiagramInfoTable();
|
|
void populateConductorTable();
|
|
void insertTerminal(Terminal *terminal);
|
|
void prepareQuery();
|
|
static QHash<QString, QString> elementInfoToString(
|
|
Element *elmt);
|
|
void bindDiagramInfoValues(QSqlQuery &query, Diagram *diagram);
|
|
|
|
private:
|
|
QPointer<QETProject> m_project;
|
|
QSqlDatabase m_data_base;
|
|
QSqlQuery m_insert_elements_query,
|
|
m_insert_element_info_query,
|
|
m_remove_element_query,
|
|
m_update_element_query,
|
|
m_insert_diagram_query,
|
|
m_remove_diagram_query,
|
|
m_insert_diagram_info_query,
|
|
m_update_diagram_info_query,
|
|
m_diagram_order_changed,
|
|
m_diagram_info_order_changed,
|
|
m_insert_terminal_query,
|
|
m_insert_conductor_query,
|
|
m_remove_conductor_query;
|
|
|
|
#ifdef QET_EXPORT_PROJECT_DB
|
|
public:
|
|
static sqlite3 *sqliteHandle(QSqlDatabase *db);
|
|
static void exportDb(projectDataBase *db,
|
|
QWidget *parent = nullptr,
|
|
const QString &caption = QString(),
|
|
const QString &dir = QString());
|
|
#endif
|
|
};
|
|
|
|
#endif // PROJECTDATABASE_H
|