SQLite Data Studio: Admin-Oberfläche
Zurück: SQLite Data Studio · Normative Regionsbelegung: SQLite Data Studio: Bereichs-Spezifikation (normativ)
Der Verwaltungsbildschirm des SQLite Data Studio: Datenbanken durchsehen, bearbeiten und entwerfen, ohne das Wiki zu verlassen.
[Live] Clean-Room-Nachbau (Azure Data Studio als UX-Vorbild, kein Fremdcode übernommen). Diese Seite beschreibt den funktionalen Ist-Stand aufgabenorientiert; die Region-für-Region-Sollstruktur (Shell-Aufbau, Aktionsinventar, Baum-Ikonen) ist auf der normativen Bereichs-Spezifikation verlinkt, nicht dupliziert.
Einschalten
enable_dbadmin ist standardmäßig an. Dass eine Installation eine Datenbankoberfläche
nicht allein dadurch bekommen soll, dass ein Plugin installiert wurde, stimmt für ein Paket,
dessen Zweck ein anderer ist und das einen Datenbankbildschirm nebenbei mitbringt – hier nicht:
dieses Paket ist das Data Studio. Ein Werkzeug, das aus ist, ist kein sichereres Werkzeug, sondern ein nicht
ausgeliefertes.
Der Bereich fehlt trotzdem? Dann hat die Instanz ihn abgeschaltet, und die Stelle ist
leicht zu übersehen: DokuWiki lädt conf/local.php und danach
conf/local.protected.php (inc/config_cascade.php), die geschützte Datei gewinnt also.
Eine Instanz kann in local.php eine 1 führen und den Bereich trotzdem aus haben. Lies
den wirksamen Wert, statt zwei Dateien zu durchsuchen.
Danach erscheint der Tab „Datenbank“ im Plugin-Admin – sichtbar nur, wenn das aktuelle Konto mindestens eine Fähigkeit der Berechtigungs- Matrix für diesen Bereich besitzt.
Shell-Aufbau
Das Studio baut keine eigene Schale: Es übergibt seine Teile der Workbench-Schale von wkfluentui (Workbench Plugin Contract v1). Objekt-Explorer links in der Sidebar, Inhalt mittig, Eigenschaften-Auxbar rechts, Command-Bar oben, Statusleiste unten; wo eine Ansicht es braucht, darunter das untere Panel.
- Command-Bar: genau ein Studio-Befehl, „Neue Abfrage“ (als Hauptschaltfläche) – der einzige, der auf das Modul als Ganzes wirkt statt auf ein Objekt. Derselbe Befehl steht in der Befehlspalette. „Dokumentation“ und den Auxbar-Schalter ergänzt der Host.
- Abfrage-Historie und Berechtigungen stehen seit 25.08.2026 im Menü „Aktionen“ der Verbindung im Objekt-Explorer. Beide betreffen eine Verbindung; eine Leiste über dem ganzen Modul kann nicht sagen, welche sie meint.
- Die frühere rechte Modul-Rail erscheint nur noch im Rückfallpfad, wenn der Host die Schale nicht übernimmt (Workbench-Vertrag oder Sidebar-Beitrag fehlt).
Details zu Regionen und Farbsemantik: SQLite Data Studio: Bereichs-Spezifikation (normativ) (normativ) und FluentUI: Admin-Bereich (vertieft) (Verhaltensregeln).
Objekt-Explorer
Zeigt alle konfigurierten Verbindungen gleichzeitig als Wurzelknoten – die aktive (per
conn-Parameter) ist aufgeklappt, andere sind Wechsel-Links; nur die aktive Verbindung
wird tatsächlich geöffnet und introspiziert. Ein einziger, geteilter Baum-Partial über alle
fünf Views (Übersicht/Struktur/Browse/Workbench/Export).
- Knotentypen: Verbindung → Tabellen/Views → Spalten/Indizes/Fremdschlüssel/Trigger, je eigenes Icon-Set (Maskenbild-CSS, keine SVG-Datei-Ladungen).
- Menü „Aktionen“ der Verbindung: „Abfragen-Assistent“, „Neue Abfrage“, „Abfrage-Historie“, „Berechtigungen“ (Matrix-Dialog, auf diese Verbindung eingeschränkt), „Verbindung testen“ und „Bearbeiten“; bei SQLite-Verbindungen zusätzlich „Sichern jetzt“, „Wiederherstellen…“, „Integritätsprüfung“, „Optimieren“ und „Sicherungen verwalten“; zuletzt „Löschen“. Jeder Eintrag wird gegen seine eigene Fähigkeit geprüft – dass man die Verbindung sieht, genügt allein nicht.
- Menü „Aktionen“ der übrigen Knoten: Tabelle „Durchsuchen“, „Struktur“, „CREATE-Statement“, „Script as DROP“, „Export“, „Import“, „Eigenschaften“, „Löschen“; Ansicht „Durchsuchen“, „CREATE-Statement“, „Eigenschaften“, „Löschen“; Tabellen-Ordner „Neue Tabelle“, „Aktualisieren“. Indizes und Trigger haben kein Menü. „Löschen“ läuft über den Zwei-Schritt-Bestätigungsdialog; im Readonly-Modus fehlen die schreibenden Einträge.
- Filterfeld unter der Titelleiste grenzt sichtbare Knoten per Substring ein (kein Ersatz für eine Server-Suche) – Details zum Baustein: Widget-Katalog → InputBox-Filter.
- Werkzeugleiste des Baums: „Neue Verbindung“, „Aktualisieren“ und der Umschalter „Alles ausklappen/einklappen“.
Tabellen-Übersicht
Landing-Hub der aktiven Verbindung: Tabellenliste mit Zeilenzahl-Schätzung, je Zeile Browse/Struktur/Export/Löschen; Command-Bar-Aktion „Neue Tabelle“ (Zwei-Schritt-Drawer: Name → landet direkt im Table Designer für Feld 2 ff.).
Table Designer (Struktur-Ansicht)
Vier Register:
- Columns: Name und Typ direkt editierbar (Name-Änderung = Umbenennen, Typ-Änderung löst den Tabellen-Neuaufbau unten aus), Lösch-Checkbox je Zeile (Primärschlüssel serverseitig geschützt). Vorschau zeigt das exakte SQL vor Ausführung; Anwenden führt in einer Transaktion aus.
- Indexes: Liste + sofortiges Anlegen/Löschen (kein Vorschau-Schritt, da unkritisch).
- Foreign Keys (nur SQLite): Liste + Hinzufügen über Vorschau/Anwenden (kann bestehende Daten verletzen), Löschen sofort (kann nie verletzen).
- Triggers (nur SQLite): Name + vollständiger, hervorgehobener SQL-Quelltext je Trigger, dazu „Bearbeiten“ und „Löschen“. Ein neuer oder geänderter Trigger wird als vollständige
CREATE TRIGGER-Anweisung eingegeben, geprüft und in der Vorschau gezeigt; Ändern verwirft den Trigger und legt ihn in derselben Transaktion neu an (Fähigkeitdesign; im Readonly-Modus nur die Liste).
Jede Zeile (Columns/Indexes/Foreign Keys) trägt einen „Eigenschaften“-Link, der die rechte Auxiliary-Bar mit einem Property-Grid der Auswahl füllt – Klick-zum-Neuladen (AJAX-Fragment), kein Live-JS-Formular.
Tabellen-Neuaufbau (Rebuild)
SQLite kennt kein ALTER TABLE … ALTER COLUMN und kein nachträgliches
ADD CONSTRAINT – beides läuft über den offiziell dokumentierten 12-Schritte-Neuaufbau
(dbadmin/RebuildPlanner.php): neue Zieltabelle anlegen, Daten spaltenweise kopieren,
Indizes/Trigger wiederherstellen, PRAGMA foreign_key_check vor COMMIT (Verletzung →
vollständiger Rollback), alles in einer Transaktion. Zusätzlich vor jedem Neuaufbau eine
VACUUM INTO-Sicherungskopie der gesamten Datenbank (Pfad wird angezeigt, nie automatisch
gelöscht). Einspaltige INTEGER PRIMARY KEY-Spalten bleiben als Rowid-Alias erhalten
(Autoincrement-Verhalten).
Datenbrowser (Browse)
Paging + Spalten-Sortierung, jede Zeile mit „Eigenschaften“-Link (volle Zeile im Auxbar). Zeilen-Aktionen: Insert/Edit (Drawer-Formular, Werte gebunden, Identifikation über Primärschlüssel), Delete (Einzelzeile oder Mehrfachauswahl → Massenlöschen, beides über den Zwei-Schritt-Bestätigungsdialog mit Stichprobenanzeige).
Query-Workbench
Multi-Statement-SQL-Konsole. Ergebnis als eigener Results/Messages-Tabstreifen – Fehler-/Erfolgstext getrennt vom Ergebnis-Grid.
- Parameter-Dialog: unbenannte
:name-Platzhalter im SQL-Text werden erkannt und vor der Ausführung als Formular abgefragt (Pflichtfeld-Gate serverseitig, nicht nur per HTML5required); jeder Wert hat eine Listen-Alternative (<details>-Aufklapper) für IN-Filter. „Letzte Werte“ persistieren client-seitig, Secrets-verdächtige Feldnamen (pass/pwd/secret/token/…) werden davon ausgeschlossen. - Entwurfs-Persistenz: der SQL-Text selbst überlebt einen Tabwechsel/Neuladen über
localStorage(beforeunload-Warnung bei ungespeicherten Änderungen), unabhängig vom Parameter-Dialog. - Abfrage-Historie: Ring-Puffer je Verbindung (nur SQL-Text/Zeitpunkt/Dauer/Zeilenzahl – nie Werte), öffnet sich als Drawer über den Eintrag „Abfrage-Historie“ im Menü „Aktionen“ der Verbindung; „In Editor übernehmen“ je Eintrag.
- Routinen-Editor-Drawer: eine bestehende Routine direkt aus dem Objekt-Baum bearbeiten, ohne den Bereich „Routinen“ zu verlassen – zwei Register (JSON, Eigenschaften), Details: Dialog-Katalog.
- Als Routine speichern: ein erfolgreich gelaufenes Statement lässt sich direkt als neue benannte Routine ablegen – Parametertypen werden aus den erkannten Platzhaltern vorgeschlagen, im Routinen-Editor verfeinerbar.
Export
- Ergebnis-Export (CSV/JSON) direkt aus der Workbench: der Client sendet nie SQL-Text, nur einen SHA-256-Hash gegen den jüngsten Historien-Eintrag der Verbindung – ausführbar ist dadurch ausschließlich ein bereits über den gegateten Konsolen-Pfad gelaufenes Statement; ein veralteter Hash wird abgewiesen. Die Wiederausführung nutzt denselben Konsolen-Pfad, wodurch der Readonly-Modus automatisch mitgilt.
- Zeilen-Kopieren (Strg+C, mit/ohne Kopfzeile) und CSV-Massenexport direkt aus dem Ergebnis-/Browse-Raster – Formel-Injection-sicher (CWE-1236: Zellen, die mit
=+-@beginnen, bekommen ein führendes Apostroph). - Eigenständiger Export-Screen für Tabellen-/View-Exporte außerhalb der Workbench (CSV/JSON/SQL).
Dialog-Katalog
| Dialog | Zweck | Muster |
|---|---|---|
Bestätigungsdialog (ConfirmDialog) | Zwei-Schritt-Bestätigung für jede destruktive Aktion (Tabelle/View/Index/Fremdschlüssel/Verbindung/Routine löschen, Massenlöschen) | Echter Server-Roundtrip statt confirm() – die erste Einreichung mutiert nichts, zeigt nur Anzahl + Stichprobe (gedeckelt auf 20). Funktioniert identisch mit/ohne JavaScript. |
Parameter-Formular (ParamForm) | Werte für :name-Platzhalter sammeln – sowohl untypisiert (Workbench-Konsole) als auch typisiert (Routinen-Test aus dem Manifest) | Serverseitiges Pflichtfeld-Gate; Listen-Alternative über <details> |
Routinen-Editor (RoutineEditorForm) | Manifest bearbeiten: Register „JSON“ (Rohtext) und „Eigenschaften“ (Formularfelder – Rückgabetyp, Parameter-Tabelle, Implementierungen) | Echte Registerkarten-Links (nav-Modus), kein Client-Toggle – jedes Register ist ein eigenständiges Formular, nie Datenkonflikt zwischen Tabs. Beide Register speichern über denselben Manifest-Validator. |
Berechtigungs-Matrix (PolicyMatrixForm) | Fähigkeiten je Gruppe/Benutzer anzeigen, speichern, entfernen – global oder je Verbindung | Details: Berechtigungen → Matrix-Dialog |
| „Connect to…“ | Neue SQLite-Verbindung ohne Pfadeingabe anlegen | Details: Verbindungen |
Readonly-Modus
Option dbadmin_readonly=1 verbietet alle Schreibvorgänge (inkl. Tabellen-Neuaufbau) und
beschränkt die Konsole auf lesende Anweisungen (SELECT/PRAGMA/EXPLAIN/SHOW/
lesendes WITH … SELECT); ein portabler, quote-/kommentar-bewusster Tokenizer erkennt auch
verschleierte Schreibversuche (z. B. schreibende Common-Table-Expressions). Übersteuert immer
die Berechtigungs-Matrix – selbst eine explizit gewährte write/design-Fähigkeit greift
in diesem Modus nicht (Details:
Berechtigungen).
Weitere Betriebsoptionen
Alle neun Einstellungen dieses Bereichs, im Konfigurationsmanager unter plugin » wksqliteds.
Die drei Einstellungen für Routinen (allowPhp, default_connection, slow_ms)
gehören nicht hierher, sondern zu Routinen →
Konfiguration.
Zugang
| Option | Default | Bedeutung |
|---|---|---|
enable_dbadmin | 1 | Bereich „Datenbank“ überhaupt anbieten. An ausgeliefert – s. Einschalten |
dbadmin_readonly | 0 | Not-Aus für alle Schreibvorgänge – s. Readonly-Modus |
dbadmin_time_limit | 180 | Sekunden, die eine Anfrage an diesen Bildschirm laufen darf; 0 = PHPs eigenes Limit unangetastet lassen |
dbadmin_time_limit wirkt ausschließlich hier – einmal je Anfrage, in
admin.php::applyTimeLimit(), und nur bei einem Wert größer null. Keine andere Seite des Wikis
ist berührt.
Die Einstellung existiert, weil beliebiges SQL, Exporte und Sicherungen die einzige Arbeit dieser
Installation sind, die Minuten laufen kann – und sie gehören alle diesem Bereich. Der Wert stand
früher in der Wiki-Konfiguration, angehängt an eine unverwandte Zuweisung, und wirkte damit beim
Lesen jener Datei: bei jeder Anfrage und jedem Kommandozeilenlauf des ganzen Wikis. Er tat
dabei zweierlei zugleich, weil PHPs Ausgangswert von der Betriebsart abhängt – im Web anheben
(30 → 180), auf der Kommandozeile deckeln (0 → 180). Die zweite Hälfte hat den mitgelieferten
Suchindexer reproduzierbar getötet. Wer mehr Zeit braucht als hier, braucht sie in der
php.ini, wo ein Betreiber sie sieht.
Wie viele Zeilen
Drei Grenzen, die leicht verwechselt werden, weil alle drei „Zeilen“ zählen – sie zählen aber an drei verschiedenen Stellen:
| Option | Default | Begrenzt | 0 bedeutet |
|---|---|---|---|
dbadmin_max_result_rows | 1000 | wie viele Zeilen geholt werden (Konsole und Export) | unbegrenzt |
dbadmin_grid_rows | 1000 | wie viele Zeilen die Workbench zeichnet | unbegrenzt |
dbadmin_buffer_cache_rows | 200 | wie viele Zeilen je Puffer als letztes Ergebnis aufbewahrt werden | unbegrenzt |
dbadmin_page_size | 12 | Zeilen je Seite im Browse-Raster | – (mindestens 1) |
Warum Holen und Zeichnen getrennt sind. Jede Zeile des Ergebnisrasters wird ein echtes
<tr>; virtuelles Scrollen gibt es hier bewusst nicht. Ein unbegrenztes Ergebnis wird damit
zu einer unbegrenzten Seite – auf dieser Instanz gemessen: 32 767 Zeilen ergaben 1 MB HTML und
2,5 s Serverzeit, und ein größeres Ergebnis stirbt mitten in der Anfrage und lässt den Browser auf
der vorigen Seite stehen. Von außen sieht das aus wie „die Abfrage tut nichts“.
Der volle geholte Satz bleibt erreichbar: CSV- und JSON-Export lesen das Ergebnis, nicht das Raster. Greift die Zeichengrenze, nennt der Hinweis über dem Raster beide Zahlen – gezeichnet und geholt –, damit niemand die kleinere für das Ergebnis hält.
dbadmin_buffer_cache_rows ist ausdrücklich unabhängig von und kleiner als die beiden anderen:
Es ist eine Vorschau zum Weiterarbeiten beim Puffer-Wechsel, nicht die maßgebliche Darstellung.
Die entsteht bei jedem Lauf neu und folgt dabei immer der Holgrenze.
dbadmin_page_size steht auf 12, nicht auf 50. Diese Seite nannte bis zum 4. August 2026 den
Wert 50; das war die alte, paketeigene Zahl. Heute ist es die hausweite Rastervorgabe – jede Liste
des Produkts beginnt bei derselben Seitengröße, damit „ein Bildschirm sind zwölf Zeilen“ überall
dasselbe heißt. Erhöhen bleibt unterstützt: Ein Browse-Raster, das über das Sichtfenster
hinausgeht, lädt beim Scrollen weiter – eine größere Seite bedeutet also vor allem weniger
Anfragen, keine andere Bedienung.
Wie viele Register
| Option | Default | Begrenzt |
|---|---|---|
dbadmin_max_query_buffers | 20 | gleichzeitig offene Abfrage-Puffer je Benutzer und Verbindung |
dbadmin_max_workspace_tabs | 20 | gleichzeitig offene Struktur-, Browse- und Wartungs-Register je Benutzer und Verbindung |
Beide Grenzen zählen getrennt. Das ist der Zweck: Wer viele Tabellenstrukturen öffnet, kann damit keine offenen Abfrage-Puffer verdrängen, und umgekehrt.
Ein stillschweigend geschlossener Puffer wäre der teurere Ausgang: Er trifft immer den Puffer, an dem gerade nicht gearbeitet wurde, und meldet sich nie.
Schema-Metadaten kommen über einen per-Backend-SchemaIntrospector (SQLite:
sqlite_master/PRAGMA; MySQL/PgSQL/SQL-Server: information_schema/Katalog; MS
Access: Best-Effort via ODBC).
Verwandte Themen
- SQLite Data Studio: Bereichs-Spezifikation (normativ) – normative Regionsbelegung, Aktionsinventar, Baum-Ikonen
- SQLite Data Studio: Berechtigungen – wer welchen Screen/welche Aktion sieht
- FluentUI: Admin-Bereich (vertieft) – Shell-Verhaltensregeln, Drawer-Regel
- SQLite Data Studio: How-to – Rezepte „Historie nutzen“, „Script as“