Link a symbol built to its partners from the project database's rows

A symbol built after opening (lazy folios) links to the partners its
link rows name, and to the symbols whose rows name it; its file's list
only adds what the rows miss. The rows keep a partner on a folio not
built until it is built, in its saved place, so a symbol no longer keeps
a list of its own: the list read from the file is dropped once opening
has filled the database. pendingLinks(), waitingLinks(),
keepsSavedLinks(), linksToSave() and QETProject::waitingLinkTargets()
go; the callers that asked a symbol for its waiting partners ask the
database (waitingPartners()).

When its links change, a symbol's rows are written from its built
partners and the waiting partners its rows held, in their order
(rowsToWrite()), so a full rewrite of the table keeps them too.

A symbol built alone as a partner on a folio not built
(Diagram::buildSymbols()) counts as built: its rows are kept, it is not
waiting (waitingSymbols(), waitingPartners()), so saving does not build
its folio, and removing it does not remove the rows naming it. A row
naming a placed symbol that has not linked yet (its folio being built)
is kept too. At opening the database holds no link until its fill
(forgetLinks()); the symbols read their files' lists until then, and the
fill takes their order: a symbol's own rows, its list, then the rows
naming it. The symbols waiting on folios not built are cached and
updated as folios are built.

QET_CHECK_LINK_ROWS now checks the rows against the links: each built
partner in its order, no other row but to a folio not built.

tst_resaveunchanged::undoKeepsLinksToUnbuiltFolios: m_000 opened with
lazy folios, a contact, its folio or its coil's folio (not built)
removed, then undone: every link saved as before.

QETZ-DB-FIRST stage 2a-3.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ispyisail
2026-10-18 22:22:57 +13:00
parent b473a07b7d
commit 9a41e01187
10 changed files with 474 additions and 183 deletions
+21 -2
View File
@@ -18,6 +18,7 @@
#ifndef PROJECTDATABASE_H
#define PROJECTDATABASE_H
#include <functional>
#include <QObject>
#include <QSqlDatabase>
#include <QSqlQuery>
@@ -156,6 +157,14 @@ class projectDataBase : public QObject
QStringList conductorPropertiesMismatches() const;
QStringList linkRowMismatches();
bool savedLinks(const Element *element, QList<std::pair<QUuid, int>> *links);
//The link rows are written (opening filled them): a symbol
//built links from them (Element::initLink())
bool holdsLinks() const {return m_holds_links;}
void forgetLinks() {m_holds_links = false;}
QList<std::pair<QUuid, int>> partnersToLink(const QUuid &element);
QList<std::pair<QUuid, int>> linkRowsOf(const QUuid &element) const;
QSet<QUuid> waitingPartners(const QUuid &element, const QSet<QUuid> &waiting);
QSet<QUuid> waitingSymbols() const;
//Fill the three stores from a project's document before its
//folios are built, then, once
@@ -255,8 +264,12 @@ class projectDataBase : public QObject
void populateConductorTable();
void populateLinkTable();
void flushLinks();
void insertLinkRows(QSqlQuery &insert, Element *element, const QSet<QUuid> &waiting);
QSet<QUuid> waitingSymbols() const;
void insertLinkRows(QSqlQuery &insert, Element *element, const std::function<bool(const QUuid &)> &waiting,
const QList<std::pair<QUuid, int>> &old_rows);
bool builtAlone(Element *element) const;
bool linksLater(const QUuid &uuid) const;
QList<std::pair<QUuid, int>> rowsToWrite(Element *element, const std::function<bool(const QUuid &)> &waiting,
const QList<std::pair<QUuid, int>> &old_rows) const;
void populateDrawingItemTables();
bool populateFromDocument(const QDomDocument &document, QString *why = nullptr);
bool writeDrawingItem(QObject *object);
@@ -332,6 +345,12 @@ class projectDataBase : public QObject
//so the rows are written when next read, as drawing items are.
QList<QPointer<Element>> m_dirty_link_elements;
QSqlQuery m_saved_links_query;
bool m_holds_links = false;
/// waitingSymbols() as it was last, for these folios not built
/// and this count of symbols built alone on them
mutable QList<Diagram *> m_waiting_folios;
mutable int m_waiting_alone = 0;
mutable QSet<QUuid> m_waiting_symbols;
//Elements moved since their folio cell was last written: a move
//sends xChanged and yChanged for every step of a drag, so the
//cell is written when next read, as drawing items are.