Skip to content

project_database DE

ispyisail edited this page Sep 11, 2026 · 1 revision

Die Projektdatenbank

QElectroTech baut fΓΌr jedes geΓΆffnete Projekt eine SQLite-Datenbank auf. Es lohnt sich, genau zu sagen, was diese Datenbank ist, denn ihr Name legt eine Annahme nahe, die nicht zutrifft:

Die Projektdatenbank ist ein abgeleiteter Cache im Arbeitsspeicher. Sie wird bei jedem Γ–ffnen des Projekts aus dem .qet-XML neu aufgebaut und nie in die Projektdatei zurΓΌckgeschrieben. Allein das XML ist dauerhaft.

Alles Weitere auf dieser Seite folgt aus diesem einen Satz.

Quelle: sources/dataBase/projectdatabase.{h,cpp}.


1. Wozu sie da ist

β€žListe alle Bauteile dieses Projekts mit Herstellerreferenzen, nach Folio gruppiertβ€œ aus einer Grafikszene zu beantworten, heißt Tausende von QGraphicsItem zu durchlaufen und Zeichenketten zu vergleichen. Aus einer Tabelle beantwortet, ist es ein SELECT.

QET hΓ€lt dieselbe Information deshalb in einer zweiten Form vor, die fΓΌr Abfragen taugt, und nutzt sie fΓΌr das, was von Natur aus eine Abfrage ist:

Nutzer Was gelesen wird
StΓΌcklistentabellen auf einem Folio element_nomenclature_view, ΓΌber ProjectDBModel
Der Abfrage-Assistent der StΓΌckliste jede der Sichten, zusammengesetzt in ElementQueryWidget
Dialog der Verdrahtungsliste wiring_list_view
--export-bom (Kommandozeile) element_nomenclature_view
--export-wires, --export-cables wiring_list_view
Folio-Übersichtstabellen project_summary_view

Nichts davon ist Speicherung. Jedes davon ist ein Bericht ΓΌber Daten, die im XML bereits vorliegen.


2. Lebenszyklus

QETProject erzeugt
    └── projectDataBase erzeugt  β†’  createDataBase()
                                     β”œβ”€β”€ ΓΆffnet eine namenlose SQLite-Verbindung
                                     β”œβ”€β”€ CREATE TABLE Γ— 6, CREATE VIEW Γ— 3
                                     └── updateDB()
Projekt-XML gelesen
    └── updateDB()   ← vollstΓ€ndiger Neuaufbau, einmal, nach allem Laden
Benutzer bearbeitet das Folio
    └── addElement / removeElement / elementInfoChanged
        addDiagram  / removeDiagram / diagramInfoChanged / diagramOrderChanged
        addConductor/ removeConductor / updateConductor      ← inkrementell
Projekt geschlossen
    └── Datenbank verworfen

QSqlDatabase::addDatabase("QSQLITE", …) wird ohne setDatabaseName() aufgerufen; es gibt also keine Datei auf der Platte, auf die die Verbindung zeigen kΓΆnnte. WΓ€hrend des Ladens sind die Signale der Datenbank blockiert, und am Ende lΓ€uft ein einziges updateDB() statt eines EinfΓΌgevorgangs je Objekt wΓ€hrend des Szenenaufbaus.

Direkt nach dem Γ–ffnen werden drei PRAGMAs gesetzt β€” temp_store = MEMORY, journal_mode = MEMORY, synchronous = OFF. FΓΌr eine Datenbank, an der einem liegt, wΓ€ren diese Einstellungen leichtsinnig. Hier sind sie genau deshalb richtig, weil ein Totalverlust nichts kostet: Beim nΓ€chsten Γ–ffnen wird ohnehin neu aufgebaut.

QETProject::readProjectXml() protokolliert die Dauer jeder Ladephase, den Datenbankaufbau eingeschlossen. Die Kosten fΓΌr ein bestimmtes Projekt lassen sich also direkt der Konsolenausgabe entnehmen, statt geschΓ€tzt zu werden.


3. Schema

Sechs Tabellen:

Tabelle SchlΓΌssel Anmerkungen
diagram uuid dazu pos, die Folio-Reihenfolge
element uuid diagram_uuid, pos, type, sub_type
diagram_info diagram_uuid je eine Spalte pro QETInformation::diagramInfoKeys() β€” heute 9
element_info element_uuid je eine Spalte pro QETInformation::elementInfoKeys() β€” heute 57
terminal (uuid, element_uuid) siehe Β§4
conductor uuid beide Enden als Paare (Klemmen-uuid, Element-uuid)

Drei Sichten: element_nomenclature_view, project_summary_view, wiring_list_view.

Man beachte, was diese Spaltenlisten bedeuten: das Schema wird zur Laufzeit aus elementInfoKeys() erzeugt. Ein neues Elementinformationsfeld fΓΌgt automatisch eine Spalte hinzu, ohne Migration und ohne Schemaversion β€” denn es gibt keine bestehende Datenbank zu migrieren. Das ist die praktisch wichtigste Folge daraus, dass der Cache abgeleitet ist.

Der Filter sitzt in der Sicht, nicht in der Tabelle

element enthΓ€lt alle Elementtypen, Slaves und Folioverweise eingeschlossen. Die EinschrΓ€nkung auf β€žwas eine StΓΌckliste nennen sollteβ€œ (type IN ('simple','terminal','master','thumbnail')) geschieht innerhalb von element_nomenclature_view.

Das war nicht immer so, und der Grund fΓΌr die Γ„nderung ist lehrreich: Lag der Filter in der Tabelle, fehlte ein Slave-Element (ein Relaiskontakt) in der Datenbank vollstΓ€ndig β€” jeder andere Leser der Tabelle, etwa die Verdrahtungsliste, verlor damit stillschweigend jeden Leiter, der an einem Relaiskontakt endete. Die Ansicht einer StΓΌckliste darΓΌber, was eine Position ist, gehΓΆrt nicht in das Modell, das ein Projekt von sich selbst hat.


4. IdentitΓ€t, und warum Klemmen schwierig sind

Zeilen brauchen stabile SchlΓΌssel. Elemente und Folios haben echte UUIDs, also kein Problem. Klemmen nicht.

Terminal::uuid() stammt aus der Katalogdefinition .elmt. Es bezeichnet eine Klemmenposition in einem Symbol β€” β€ždie obere Klemme eines SchΓΌtzesβ€œ β€” und ist daher fΓΌr jede platzierte Instanz dieses Symbols identisch. Zudem ist es bei jedem Element leer, das vor EinfΓΌhrung dieses Feldes erstellt wurde, also beim grâßten Teil der installierten Sammlung.

Zwei Konsequenzen, beide behandelt:

  • Eine Klemmeninstanz ist nur als Paar (uuid, element_uuid) eindeutig. Deshalb ist dieses Paar β€” und nicht uuid allein β€” der PrimΓ€rschlΓΌssel der Klemmentabelle und das Ziel der FremdschlΓΌssel der Leitertabelle.
  • Terminal::stableUuid() liefert eine IdentitΓ€t, wenn die Definition keine vorgibt: als UUID v5, abgeleitet aus lokaler Position und Ausrichtung der Klemme innerhalb ihres Elements β€” derselben Grundlage, die das Projektformat ohnehin schon nutzt, um einen Leiter einer Klemme zuzuordnen. Namen bleiben bewusst außen vor, denn QET schreibt eine Klemme namens _ als unbenannt zurΓΌck, wodurch sich die IdentitΓ€t beim ersten erneuten Speichern Γ€ndern wΓΌrde.

projectDataBase::excludedConductorCount() meldet, wie viele Leiter ΓΌberhaupt nicht indizierbar waren β€” gezΓ€hlt aus der lebenden Szene, nicht aus der Datenbank, β€žgenau deshalb, weil die Datenbank der Ort ist, an dem diese Leiter nicht sindβ€œ. Das erlaubt einer Verdrahtungsliste zu sagen β€žN DrΓ€hte fehlen, und zwar aus diesem Grundβ€œ, statt eine unvollstΓ€ndige Liste als vollstΓ€ndig auszugeben.

Das ist die Randbedingung, die man bei jeder kΓΌnftigen Persistenzarbeit im Blick behalten muss. Solange die Datenbank abgeleitet ist, kostet eine aus der Geometrie erratene KlemmenidentitΓ€t einen Cache-Fehlschlag. Als Dateiformat wird aus derselben SchΓ€tzung eine endgΓΌltige, einmalige Migration der Projekte aller Anwender.


5. Was aus β€žabgeleitetβ€œ folgt

Weil sie abgeleitet ist… …gilt dies
Bei jedem Γ–ffnen neu aufgebaut Keine Schemaversion, keine Migrationen, nie
Nie ins .qet geschrieben Eine falsche Zeile kostet nichts β€” neu ΓΆffnen, und sie ist weg
Das XML ist maßgeblich Die Datenbank kann der Zeichnung nicht widersprechen; tut sie es doch, irrt die Datenbank
Beim Schließen verworfen synchronous = OFF und Verwandtes sind unbedenklich
Lebt in einem Prozess Sie ist weder geteilt noch nebenlΓ€ufig noch mehrbenutzerfΓ€hig

Und die Kehrseite, ebenso wahr:

Weil sie abgeleitet ist… …gilt auch dies
Nichts überlebt das Schließen Alles, was nur die Datenbank weiß, geht verloren
Beim Γ–ffnen vollstΓ€ndig neu aufgebaut Die Γ–ffnungskosten wachsen mit der Projektgrâße
Nicht in der Datei enthalten Zwei Personen kΓΆnnen nicht dieselbe Projektdatenbank abfragen

6. Selbst nachsehen

Mit QET_EXPORT_PROJECT_DB ΓΌbersetzte Programme haben einen MenΓΌeintrag, Interne Projektdatenbank exportieren, der die lebende Datenbank ΓΌber die Backup-API von SQLite in eine .sqlite-Datei kopiert. Die CMake-Option steht standardmÀßig auf OFF, doch die offiziellen Pakete fΓΌr Windows, macOS, Flatpak und Snap schalten sie alle ein β€” in einer verΓΆffentlichten Version ist der Eintrag also normalerweise vorhanden.

Die exportierte Datei ist eine Momentaufnahme zur Einsicht. Sie zu bearbeiten Γ€ndert nichts: Niemand liest sie je zurΓΌck.

sqlite3 meinprojekt.sqlite ".schema"
sqlite3 meinprojekt.sqlite "SELECT label, designation FROM element_nomenclature_view LIMIT 20;"

7. Was sie nicht ist

Sie ist nicht die Projektdatei, keine gemeinsame Datenbank, mit der sich ein Team verbindet, und nicht die Architektur aus Bauteildatenbank plus Zeichnungsansicht, wie sie Werkzeuge wie EPLAN haben. Ein Projekt bleibt eine einzige XML-Datei; die Datenbank ist ein Abfrageindex darΓΌber, der lebt, solange das Fenster offen ist.

Ob das so bleiben soll, ist eine offene Frage β€” siehe die Seiten Vision und Entwicklungs-Roadmap. Jeder Schritt hin zu Persistenz ist eine Γ„nderung des Dateiformats, und das Problem der KlemmenidentitΓ€t aus Β§4 ist deren erste echte HΓΌrde.

Bis eine solche Entscheidung fÀllt, lohnt beim Hinzufügen von Funktionen eine Faustregel: Erzeugen Sie keinen Zustand, den nur das XML kennt, und keinen, den nur die Datenbank kennt. Ersteres macht den Cache unvollstÀndig; Letzteres überlebt kein Schließen.

Getting Started

Home

🌐 Languages β€” English Β· FranΓ§ais Β· Deutsch

Downloads

Windows without admin rights β€” the portable archive, no installer

Quick Start Guide

User Manual

FAQ

Tips & Tricks

Guides

Conductors β€” wire properties, what feeds which export, cables, and hops where wires cross

Wires per terminal β€” limit the wires on a terminal, chain wiring instead of stars

Printing and exporting β€” paper, PDF, images, and what each path does differently

Linking elements β€” master, slave, terminal

PLC modules β€” I/O tables and linking a wire to a specific point

Using the element editor β€” drawing tools, saving, checks

Generic devices β€” a quick box symbol with terminals on any side, made by a wizard (pending)

Grid size and element size β€” why symbols aren't all the same scale, and scaling one without leaving the grid

Preferences reference β€” what each settings page does

Saving and loading settings β€” your whole setup in one file, to copy or keep

Keyboard-only control β€” mouseless QET, and what still needs a mouse

Mouse modifiers β€” what Shift, Ctrl and Alt change while you drag

3D mouse β€” SpaceMouse pan, zoom and buttons

Aligning items β€” snap symbols back to the grid, or line them up

Pictures on a sheet β€” labels, crop, transparency, what they cost in the file

Arcs and curved wires β€” the Arc tool, pulling an arc in or out, rounding a corner with a fillet, dashed arcs for lighting layouts

Grouping items β€” select, move and copy several items as one

Finding your place on a sheet β€” go to a cell like B13 or 4-B7, keep the headers in sight, show the cell limits, zoom and pan

Showing and hiding kinds of items β€” hide texts, wire numbers, shapes, pictures, tables or cross-references on every sheet

Drawing faster β€” place without dragging, the S shortcut bar, command search, gestures

Customising QElectroTech β€” keys, toolbar size and contents, the gesture ring (partly pending)

Managing collections β€” folders, writability, building your own shortlist

Templates β€” reusable multi-element blocks, placed by double-click or drag

Search & Replace β€” bulk property changes

Building a nomenclature query β€” the BOM/summary table builder

Linking wires across pages β€” sheet reports

Variables & formulas β€” %f, %{label}, sequences

Auto-numbering β€” schemes, sequences, freezing

Terminal strips β€” strips, levels, bridges

Title block templates β€” the .titleblock format

Importing EPLAN parts (.edz) β€” EPLAN Data Portal

DXF import & export β€” two unrelated features, one format; command-line export and layers

The project database β€” the in-memory SQLite cache

File formats
Elements XML
Project XML
Development

Building from Source

Contributing Code

Automating QET β€” CLI, XML formats, external tools

CLI Reference β€” command line usage

JavaScript Scripting β€” --run, geometry editing, undo

MCP server β€” let an AI assistant read, verify and edit projects

Connecting an AI assistant β€” setup for Claude, Copilot, Gemini, Codex, Cursor, LM Studio

Script buttons β€” stored scripts with an icon, by hand or by an assistant

Live mode β€” an assistant working in the open project while you watch

Macro recorder β€” record a task by hand, for an assistant to script

Development Roadmap

Vision β€” proposal, under discussion

Developer Tools

About

Features

History

Community

License

Contributing to this Wiki

Clone this wiki locally