mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-09-26 11:54:14 +02:00
46c35d2297
Every structural question this API could answer, it answered by walking live objects. The project builds a SQLite database that already knows most of them, and nothing outside the application could reach it. tables() what is queryable, tables and views query(sql) rows, one object per row queryError() why the last one returned nothing This is not a new door. QElectroTech already ships a "Requête SQL personnalisée" box in the element-query dialog where a user types arbitrary SQL, guarded by projectDataBase::isReadOnlySelect(); query() goes through projectDataBase::newQuery(), which applies that same rule and returns the same rejection message. A script gets what a user already has, and neither can write: DELETE, UPDATE and a chained "SELECT 1; DROP TABLE" are all refused before reaching SQLite. An empty result and a failure are told apart. query() returns no rows for both, so queryError() carries the reason -- a refusal, or SQLite's own message for a bad column -- and is empty when the query simply matched nothing. Conflating those is how a silent typo in a column name becomes "there are no such elements". No updateDB() before querying, and that is a measured decision rather than an omission. A script that has just edited something is the expected caller, so a stale cache was the obvious hazard; but projectDataBase maintains itself incrementally through addElement(), elementInfoChanged(), addConductor() and the rest, which the undo commands behind every edit already call. Tested both ways on the cases most likely to go stale -- an element added and labelled, a conductor property changed -- each queried immediately afterwards through both the table and the view. Identical counts with the rebuild and without it, and updateDB() repopulates every table, so calling it per query would have been real cost for no benefit. The comment says so, so it is not added back on the assumption it must be needed. The views are the surface to depend on: element_nomenclature_view, project_summary_view and wiring_list_view exist to be queried. The tables are how the cache is arranged today and a column may move -- which is why tables() lists both and the header says which is which. Verified against examples/industrial.qet, the largest shipped project: 618 elements counted, the busiest wire numbers ranked (0VDC 93 times, 24V2 64), and duplicate element labels found by GROUP BY ... HAVING -- V6 seven times, V5 six -- which is a design-rule question no tool here could previously ask. Qt 6.10.2, ctest matches master. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>