mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-09-27 12:34:14 +02:00
Fix element_info orphan row causing UNIQUE constraint errors on undo
Reviving #664, closed 2026-09-18 purely to clear a maintainer review backlog (#630), not on merit; not superseded. Rewritten fresh against current master rather than merged from the old branch -- that branch predates the Qt6-only switch and much of dataBase/projectdatabase.cpp's later rewrite, and the two had diverged too far for a textual merge to be trustworthy. projectDataBase::removeElement() only ran DELETE FROM element WHERE uuid=:uuid. It never touched element_info, even though every element also has a row there (element_uuid is its PRIMARY KEY, with a FOREIGN KEY back to element.uuid that isn't enforced by this connection -- no ON DELETE CASCADE in effect). So deleting an element left its element_info row orphaned. Re-adding an element with that same uuid later -- undo of that same deletion, or a redo replaying it -- goes through addElement(), which INSERTs into both tables. The element insert succeeds (that row really was removed). The element_info insert hits the orphaned row's primary key and fails, silently: the error is logged and swallowed, so the element re-enters the scene with no element_info row at all, and nothing later re-syncs it. removeDiagram() already cascades this cleanup when a whole folio is removed (a later, unrelated addition) -- confirmed on current master -- but that path never runs for a single element removed on its own, which is the case this fixes. Verified on the built binary, not just read: placed an element, deleted it (Ctrl+A, Delete), undid the deletion (Ctrl+Z). Reverting just this fix and repeating the identical sequence reproduces the exact reported error: Debug: projectDataBase::addElement insert element info error : QSqlError("1555", "Unable to fetch row", "UNIQUE constraint failed: element_info.element_uuid") With the fix, the same sequence produces nothing. Qt 6.10.2, ctest 13/13. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -319,10 +319,23 @@ void projectDataBase::addElement(Element *element)
|
||||
void projectDataBase::removeElement(Element *element)
|
||||
{
|
||||
m_content_changed = true;
|
||||
bool changed = false;
|
||||
|
||||
m_remove_element_query.bindValue(":uuid", element->uuid().toString());
|
||||
if(!m_remove_element_query.exec()) {
|
||||
qDebug() << "projectDataBase::removeElement remove error : " << m_remove_element_query.lastError();
|
||||
if (m_remove_element_query.exec()) {
|
||||
changed = true;
|
||||
} else {
|
||||
qDebug() << "projectDataBase::removeElement remove error : " << m_remove_element_query.lastError();
|
||||
}
|
||||
|
||||
m_remove_element_info_query.bindValue(":uuid", element->uuid().toString());
|
||||
if (m_remove_element_info_query.exec()) {
|
||||
changed = true;
|
||||
} else {
|
||||
qDebug() << "projectDataBase::removeElement remove element_info error : " << m_remove_element_info_query.lastError();
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
emit dataBaseUpdated();
|
||||
}
|
||||
}
|
||||
@@ -1159,6 +1172,21 @@ void projectDataBase::prepareQuery()
|
||||
m_remove_element_query = QSqlQuery(m_data_base);
|
||||
m_remove_element_query.prepare(remove_element);
|
||||
|
||||
//REMOVE ELEMENT INFO
|
||||
//element_info has no ON DELETE CASCADE (foreign keys aren't
|
||||
//enforced by this connection), so removeElement() must clear it
|
||||
//explicitly. Without this, the row is orphaned under the removed
|
||||
//element's uuid, and re-adding an element with that same uuid
|
||||
//later -- undo of this same removal, or a redo replaying it --
|
||||
//hits element_info's PRIMARY KEY constraint on element_uuid: the
|
||||
//element re-add succeeds, but its element_info insert silently
|
||||
//fails and is lost. removeDiagram()'s cascade already clears this
|
||||
//table when a whole folio goes, but that does not run for a
|
||||
//single element removed on its own.
|
||||
QString remove_element_info("DELETE FROM element_info WHERE element_uuid=:uuid");
|
||||
m_remove_element_info_query = QSqlQuery(m_data_base);
|
||||
m_remove_element_info_query.prepare(remove_element_info);
|
||||
|
||||
//UPDATE ELEMENT INFO
|
||||
QString update_str("UPDATE element_info SET ");
|
||||
for (auto string : QETInformation::elementInfoKeys()) {
|
||||
|
||||
Reference in New Issue
Block a user