JsonSQL Dokumentation

v1.0.7 – Stand: 2025-05-10

Einführung

Die leistungsstarke, flexible und leichtgewichtige Lösung für SQL-ähnliche Abfragen auf JSON-Daten.

Was ist JsonSQL?

JsonSQL ist eine SQL-ähnliche Abfragesprache speziell für die Arbeit mit JSON-Daten. Es erlaubt dir, Daten zu filtern, zu sortieren, zu gruppieren, zu verbinden und zu aggregieren – alles in der Art und Weise, wie du es von SQL-Datenbanken kennst. Aber statt auf komplexe relationale Datenbanken angewiesen zu sein, arbeitet JsonSQL direkt mit deinen JSON-Dateien und bietet dir eine einfache Möglichkeit, deine Daten abzufragen und zu bearbeiten.

Einfachheit

Keine komplexen Datenbankverbindungen – JsonSQL arbeitet direkt mit deinen JSON-Daten.

Leistung

JsonSQL ermöglicht schnelle SQL-ähnliche Abfragen auf JSON-Dateien, ohne eine Datenbank zu benötigen.

Flexibilität

Ideal für kleine bis mittlere Datenmengen. Leicht in Webanwendungen und APIs zu integrieren.

Warum JsonSQL?

  • Einfachheit: Du musst keine komplexen Datenbankverbindungen oder Konfigurationen einrichten. JsonSQL arbeitet direkt mit deinen bestehenden JSON-Daten.
  • Leistung: JsonSQL bietet eine schnelle, in-memory Verarbeitung von Daten und ermöglicht schnelle SQL-ähnliche Abfragen auf JSON-Dateien.
  • Flexibilität: JsonSQL ist einfach zu integrieren und funktioniert hervorragend mit bestehenden Webanwendungen und APIs.
  • Vielseitigkeit: Du kannst JsonSQL in einer Vielzahl von Szenarien verwenden – sei es zum Erstellen von Prototypen, für Tests, bei kleinen Datenmengen oder als Alternative zu klassischen Datenbanken.

🔍 Vergleich: Klassische Datenbank vs. JsonSQL

Merkmal Klassische Datenbank
(z. B. MySQL, PostgreSQL)
JsonSQL
Installation Muss installiert & konfiguriert werden Keine Installation nötig
(nur PHP + JSON)
Verbindung Benötigt Datenbank-Server & Verbindung Arbeitet direkt mit lokalen JSON-Dateien
Komplexität Hoch – mit Benutzer, Rechten, Tabellen etc. Einfach – JSON-Dateien als Datenbasis
Abfrage-Sprache SQL (Structured Query Language) SQL-ähnlich, speziell für JSON
Leistung Sehr performant bei großen Datenmengen Schnell bei kleinen/mittleren Daten
Speicherung Relationale Tabellen Strukturierte JSON-Dateien
Einsatzgebiet Enterprise, große Webanwendungen Prototypen, kleine Projekte, APIs
Abhängigkeiten DB-Server, Treiber, evtl. ORM Keine externen Abhängigkeiten
Portabilität Weniger flexibel (Dump/Import nötig) Leicht kopierbar als einfache Dateien

Bereit, loszulegen?

Diese Dokumentation führt dich Schritt für Schritt durch alle grundlegenden Funktionen von JsonSQL. Du wirst lernen, wie du die API effizient nutzt und dabei die Kraft von SQL-ähnlichen Abfragen für deine JSON-Daten entfesseln kannst.

Aber am schnellsten kommst du rein durch Learning by Doing – unsere Demos helfen dir dabei, direkt loszulegen und JsonSQL im echten Einsatz zu erleben!


Installation von JsonSQL

Die Installation von JsonSQL ist simpel und flexibel – du kannst es direkt in deine bestehende Projektstruktur einbauen oder als Standalone verwenden. JsonSQL benötigt keine externe Datenbank und arbeitet direkt mit JSON-Dateien.

Schritt 1: JsonSQL in dein Projekt integrieren

JsonSQL ist in einem vendor/JsonSQL-Ordner organisiert. Falls dein Projekt bereits einen vendor/-Ordner verwendet, kannst du einfach den JsonSQL-Ordner dorthin kopieren.

Falls du noch keinen vendor/-Ordner hast, kannst du den gesamten mitgelieferten Ordner übernehmen:


/dein_projekt/
├── vendor/
│   └── JsonSQL/
│       └── src/
│           ├── JsonSQL.php
│           └── ...
├── testdb/
│   └── aggregat_demo/
│       ├── aggregat_demo_data.json
│       └── aggregat_demo_data.system.json
└── index.php
      

Schritt 2: JsonSQL in deinem Skript einbinden

Füge in deinem PHP-Skript folgenden Code ein, um JsonSQL korrekt zu laden:


// Pfad zur JsonSQL-Klasse setzen
$JsonSQLpath = __DIR__ . '/../vendor/JsonSQL/src/JsonSQL.php';

if (!file_exists($JsonSQLpath)) {
    die("❌ JsonSQL.php nicht gefunden!");
}

require_once $JsonSQLpath;

// Wichtig: Namensraum verwenden
use Src\JsonSQL;

// Instanzierung und Datenbank-Zuordnung
$db = new JsonSQL([
    'aggregat_demo' => __DIR__ . '/../testdb/aggregat_demo'
]);

$table = 'aggregat_demo_data';
$db->use('aggregat_demo')->setTable($table);

// Jetzt kannst du Abfragen starten!
$data = $db->get(); // Alle Datensätze holen
      

Hinweis: Falls du mit mehreren Datenbanken oder Tabellen arbeitest, kannst du über use() die aktive Datenbank und über setTable() die Tabelle wählen. Mehr dazu in den folgenden Abschnitten.

Schritt 3: Was passiert im Konstruktor?

Die JsonSQL-Klasse erwartet im Konstruktor ein Array mit dem Namen und Pfad deiner Datenbanken. Beispiel:


new JsonSQL([
  'demo' => '/pfad/zur/demo-datenbank',
  'produkte' => '/pfad/zur/produktdatenbank'
]);
      

Danach kannst du über use('demo') die gewünschte Datenbank aktivieren.

Schritt 4: Sicherheit und Fehlerbehandlung

JsonSQL bietet dir maximale Kontrolle – aber du solltest ein paar Dinge beachten:

  • try/catch: Um dein Projekt robuster zu machen, empfiehlt sich eine globale Fehlerbehandlung:

try {
    require_once __DIR__ . '/../vendor/JsonSQL/src/JsonSQL.php';
    use Src\JsonSQL;

    $db = new JsonSQL([
        'demo' => __DIR__ . '/../testdb/demo'
    ]);
    $db->use('demo')->setTable('testdata');

    $data = $db->get();
    // Ergebnis anzeigen oder weiterverarbeiten
} catch (Throwable $e) {
    echo "❌ Fehler beim Zugriff auf JsonSQL: " . $e->getMessage();
}
      
  • Dateiberechtigungen: Stelle sicher, dass der Webserver read/write-Zugriff auf die Datenordner hat.
  • Verzeichnisse trennen: Lege Daten außerhalb des public_html-Ordners ab, wenn du JsonSQL produktiv nutzt.
  • Backup: Nutze regelmäßige Backups deiner JSON-Daten, z. B. über eine automatische Kopie bei jedem insert() oder update().

Weiterführende Nutzung

Mehr Infos zur Nutzung von insert(), update(), Abfragen, Gruppierungen, Verschlüsselung, Auto-Feldern und Co findest du in den weiteren Doku-Abschnitten oder unter https://teitge.de/jsonsql-demos/.

Einstieg: Direkt loslegen statt Theorie pauken

Wir wollen dich nicht stundenlang mit trockener Theorie langweilen – stattdessen steigen wir direkt mit einer funktionierenden Demo ein. Du kannst sie hier live ausprobieren:

Was passiert in dieser Demo?


$db = new JsonSQL(['demo' => __DIR__ . '/../testdb']);
$db->use('demo');
$table = 'hello';
$db->truncate($table);
$db->from($table)->insert([ 'name' => 'Alice', 'email' => 'alice@example.com' ]);
$db->insert([ 'name' => 'Bob', 'email' => 'bob@example.com' ]);
$rows = $db->from($table)->get();
  

🧩 Schritt für Schritt erklärt

1. JsonSQL einbinden und Instanz erzeugen

Die Klasse wird per require_once eingebunden und dann mit einer Datenbank-Liste initialisiert:


require_once __DIR__ . '/../vendor/JsonSQL/src/JsonSQL.php';
use Src\JsonSQL;

$db = new JsonSQL(['demo' => __DIR__ . '/../testdb']);
  
2. Datenbank und Tabelle festlegen

Mit $db->use('demo') wählst du deine Datenbank, anschließend setzt du die Tabelle mit setTable() oder from().

Unterschied:

  • setTable(): speichert die Tabelle dauerhaft in der Instanz
  • from(): verwendet die Tabelle nur temporär
  • truncate(): leert oder erstellt die Tabelle neu – nützlich für Demos!
3. Daten einfügen mit insert()

$db->from($table)->insert([
  'name' => 'Alice',
  'email' => 'alice@example.com'
]);

Die Daten werden als Array mit Schlüssel/Wert-Paaren übergeben. JsonSQL legt die Felder bei Bedarf automatisch an.

Auch eine zweite Zeile ist möglich:


$db->insert([ 'name' => 'Bob', 'email' => 'bob@example.com' ]);

Mehrere Datensätze gleichzeitig kannst du als Array von Arrays übergeben:


$db->insert([
  [ 'name' => 'Carol', 'email' => 'carol@example.com' ],
  [ 'name' => 'Dave',  'email' => 'dave@example.com'  ]
]);

JsonSQL prüft bei jedem Datensatz automatisch auf doppelte Einträge (z. B. anhand eindeutiger Felder) und ignoriert diese bei Bedarf.

5. Bonus: FancyVarDump aktiviert

Mit FancyDumpVar kannst du das $db-Objekt sowie die Rückgaben direkt inspizieren. Einfach über den Footer aktivieren oder im Code:


$debugger->addInfoText('JsonSQL Object');
$debugger->dump($db);
$debugger->addInfoText('Die fertigen Daten');
$debugger->dump($rows);
  

🖥️ Bootstrap-Ausgabe mit PHP-Loop

Die fertige Liste wird mit Bootstrap-HTML ausgegeben, das ward dann auch schon.

✅ Fazit

Diese erste Demo zeigt dir den typischen JsonSQL-Workflow:

  1. Datenbank wählen: use()
  2. Tabelle setzen: from() oder setTable()
  3. Daten einfügen: insert()
  4. Daten holen: get()
  5. Daten anzeigen mit HTML oder Debugger

Ohne echte Datenbank, ohne Setup, aber mit voller SQL-Logik – willkommen bei JsonSQL! 🚀

Architektur & Grundlagen

Nachdem du in der Demo einen ersten Eindruck von JsonSQL bekommen hast, steigen wir nun etwas tiefer ein und schauen uns an, wie das System unter der Haube funktioniert. JsonSQL ist modular aufgebaut und besteht aus einer Hauptklasse sowie verschiedenen Spezialmodulen, die bestimmte Aufgaben übernehmen.

Was ist JsonSQL?

JsonSQL ist eine leichtgewichtige PHP-Klasse, die SQL-ähnliche Operationen auf JSON-Dateien ermöglicht – ohne echte Datenbank im Hintergrund. Sie ist ideal für kleine Projekte, Admin-Tools, Demo-Anwendungen oder embedded Systeme, bei denen keine komplexe DB nötig oder möglich ist.

Die Daten werden als einzelne Dateien im JSON-Format in einem Verzeichnis gespeichert und durch die Klasse mit Operationen wie insert(), select(), update() oder delete() verwaltet.

Projektstruktur und Modulaufbau

JsonSQL ist modular aufgebaut, um besser wartbar und erweiterbar zu bleiben. Die Kernstruktur liegt im Verzeichnis src/:


src/
├── JsonSQL.php        # Hauptklasse (bindet alle Module ein)
├── JS_Base.php        # Basisklasse mit allgemeinen Hilfsfunktionen
├── JS_Filters.php     # Filterlogik (where, or, and, etc.)
├── JS_Select.php      # Select-Funktion inkl. Limit, OrderBy, GroupBy
├── JS_Insert.php      # Insert-Funktionen inkl. Auto-Felder
├── JS_Update.php      # Update-Logik
├── JS_Delete.php      # Delete-Funktion
├── JS_System.php      # system.json: AutoFelder, Validierung, Defaults, usw.
├── JS_Export.php      # Export- und Import-Tools
└── JS_SQLParser.php   # Parser für einfache SQL-Strings (optional)
  

Alle Module werden automatisch in der JsonSQL.php gebündelt. Du arbeitest immer nur mit einer Instanz – die interne Logik wird dynamisch über die eingebundenen Module abgewickelt.

Eine Instanz erstellen

Um JsonSQL zu verwenden, erzeugst du eine Instanz und übergibst ein Array mit Datenbanknamen und Pfaden:


require_once __DIR__ . '/../src/JsonSQL.php';
use Src\JsonSQL;

$db = new JsonSQL([
  'demo' => __DIR__ . '/../testdb',
  'kunden' => __DIR__ . '/../kunden-db'
]);
$db->use('demo');
  

Du kannst mehrere Datenbanken definieren und bei Bedarf mit use('name') zwischen ihnen wechseln. Intern sind das jeweils nur Verzeichnisse mit JSON-Dateien.

Datenstruktur & Verzeichnis-Layout

Jede „Datenbank“ ist technisch ein Verzeichnis mit folgenden Inhalten:

  • users.json: Die Tabelle users – pro Tabelle eine JSON-Datei
  • users.system.json (optional): Strukturdefinition, Regeln und Meta-Felder für users.json
  • products.json: Weitere Tabelle
  • products.system.json (optional): Strukturdefinition für die Produkttabelle
  • backups/ (optional): Backup-Dateien deiner Tabellen (wenn aktiviert)

Beispielhafte Struktur:


testdb/
├── users.json
├── users.system.json
├── products.json
├── products.system.json
├── backups/
│   └── users_2024-12-01.json
└─

Jede Tabelle [name].json kann durch eine optionale [name].system.json ergänzt werden. Diese Datei enthält tabellenspezifische Regeln wie z. B. automatische Felder, erlaubte Typen, Pflichtfelder, Verschlüsselung oder Validierungen.

Tipp: Du kannst das Datenbankverzeichnis direkt im Explorer oder Editor öffnen und die JSON-Dateien bearbeiten – JsonSQL bleibt vollständig transparent.

Jetzt, wo du die Grundstruktur kennst, gehen wir im nächsten Kapitel ins Detail: insert(), select(), update() und delete() im praktischen Einsatz.

Kernfunktionen

In diesem Abschnitt dokumentieren wir alle Kernfunktionen der JsonSQL-Klasse im Detail. Jede Methode ist modular aufgebaut und kann mit oder ohne Tabellenbindung verwendet werden. Viele Funktionen lassen sich miteinander kombinieren und sind methodenverkettet einsetzbar.


📥 insert()

  • Rückgabewert: void – kein Rückgabewert
  • Parameter: array $records – Einzelner oder mehrere Datensätze als Array

[Trait: JS_CRUD]

Mit der Methode insert() lassen sich ein oder mehrere Datensätze in die aktuell gewählte Tabelle einfügen.

Wenn system.json nicht vorhanden ist, übernimmt JsonSQL alle Felder automatisch – ohne Validierung oder feste Felddefinitionen.

Wenn eine system.json vorhanden ist, richtet sich das Verhalten nach der Option "allowAdditionalFields":

  • true – zusätzliche Felder werden beim Insert mitgespeichert
  • false (Standard) – nur Felder, die in system.json definiert sind, werden übernommen
Wichtig: Auch wenn neue Felder in den Datensatz geschrieben werden, werden sie nicht automatisch zur system.json hinzugefügt. Die Systemtabelle muss manuell oder programmatisch erweitert werden, wenn die neuen Felder dauerhaft verwendet oder typisiert werden sollen.

$db->insert([
  'name' => 'Alice',
  'email' => 'alice@example.com'
]);

// Mehrere Einträge auf einmal
$db->insert([
  ['name' => 'Bob'],
  ['name' => 'Charlie']
]);

Wird eine system.json verwendet, folgt der Insert-Vorgang definierten Regeln:

  • Felder wie id, uuid, created_at usw. werden automatisch ergänzt.
  • Datentypen wie string, integer, float, enum usw. werden validiert.
  • Standardwerte, Min/Max-Prüfungen und Auto-Funktionen (z. B. AutoHash oder Autoincrement) werden angewendet.
⚙️ Option: allowAdditionalFields

Die system.json kann steuern, ob beim Einfügen zusätzliche Felder erlaubt sind, die nicht in der Felddefinition vorkommen. Das wird über den Schalter "allowAdditionalFields": true geregelt.


{
  "allowAdditionalFields": true,
  "fields": {
    "name": { "dataType": "string" },
    "created_at": { "dataType": "datetime" }
  }
}

Ist diese Option aktiviert, dürfen beim Insert auch neue Felder wie z. B. nickname oder info mitgegeben werden. Wenn sie deaktiviert ist, werden nur Felder übernommen, die in fields explizit definiert sind – alle anderen werden ignoriert.

🔍 Intern passiert Folgendes:
  • applyAutoFields() ergänzt alle Felder laut Systemdefinition.
  • insertAdditionalFields() prüft, ob weitere Felder erlaubt sind (via allowAdditionalFields).
  • Der finale Datensatz wird validiert und am Ende der Tabelle gespeichert.

➕ Tipp: Nutze die system.json, um deine Tabellenstruktur gezielt zu steuern und automatisch sichere, saubere Einträge zu gewährleisten.


🛠️ update()

  • Trait: JS_CRUD
  • Rückgabewert: int – Anzahl der erfolgreich aktualisierten Datensätze
  • Parameter: array $fieldsToUpdate – Zu ändernde Feld/Wert-Paare

Aktualisiert gezielt alle Datensätze in der aktuell gewählten Tabelle, die den gesetzten where()-Filtern entsprechen. Nur die gefilterten Datensätze werden angepasst – alle anderen bleiben unverändert.

Besonderheiten:

  • Die Methode ist nicht destruktiv: Nur die übergebenen Felder werden verändert.
  • Felder mit "auto_modified_timestamp": true in der system.json werden automatisch mit einem aktuellen Zeitstempel aktualisiert.
  • Die Zeitformate und Zeitzonen dieser Felder sind individuell definierbar (z. B. format, timezone).
  • Verwendet flock() zur sicheren Dateisperre beim Schreiben.

$affected = $db->from('produkte')
               ->where('kategorie', '=', 'Haushalt')
               ->update([
                   'status' => 'archiviert',
                   'sichtbar' => false
               ]);

echo "$affected Datensätze aktualisiert.";

Damit Felder automatisch mit dem aktuellen Datum/Zeit aktualisiert werden, muss in der system.json ein entsprechender Eintrag vorhanden sein:


{
  "fields": {
    "updated_at": {
      "dataType": "datetime",
      "auto_modified_timestamp": true,
      "format": "Y-m-d H:i:s",
      "timezone": "Europe/Berlin"
    }
  }
}

Diese Regelung gilt für beliebige Feldnamen. Du kannst mehrere Felder definieren, die bei jeder Änderung automatisch aktualisiert werden – mit jeweils eigenem Format und Zeitzone.

Wird where() nicht gesetzt, werden alle Datensätze in der Tabelle aktualisiert (mit Vorsicht verwenden).


🗑️ delete()

  • Trait: JS_CRUD
  • Rückgabewert: int – Anzahl gelöschter Datensätze

Löscht alle Datensätze aus der aktuell gewählten Tabelle, die den gesetzten where()-Filtern entsprechen. Die Datei wird dabei exklusiv gesperrt, um gleichzeitige Schreibzugriffe zu verhindern.

Wichtig:

  • Die Methode from() muss zuvor aufgerufen worden sein.
  • Nur Datensätze, die exakt den Filterbedingungen entsprechen, werden entfernt.
  • Die gesetzten Filter bleiben nach dem Löschen aktiv – diese müssen ggf. manuell zurückgesetzt werden.

// Einzelne Bedingung
$deleted = $db->from('produkte')
              ->where('preis', '<', 10)
              ->delete();

// Mehrere Bedingungen
$deleted = $db->from('kunden')
              ->where([
                  ['land', '=', 'DE'],
                  ['newsletter', '=', false]
              ])
              ->delete();

echo "$deleted Datensätze gelöscht.";

Die Methode gibt die Anzahl der erfolgreich gelöschten Datensätze zurück. Ein Wert von 0 bedeutet, dass kein Eintrag den Kriterien entsprach.


🎯 select()

[Trait: JS_Query]

Mit select() bestimmst du, welche Felder (Spalten) aus der aktuellen Tabelle bei der Abfrage zurückgegeben werden sollen. Diese Methode ist optional – wenn sie nicht verwendet wird oder mit '*' aufgerufen wird, werden alle Felder zurückgegeben.

Du kannst die Methode mit einem einzelnen String oder einem Array aufrufen. Aliasnamen sind möglich – z. B. "preis AS cost" – und helfen dir, Felder umzubenennen.


// Gibt alle Felder zurück
$rows = $db->from('users')->select('*')->get();

// Nur bestimmte Felder
$rows = $db->from('users')->select('id, name')->get();

// Mit Aliasnamen
$rows = $db->from('products')->select('title AS Produktname, price AS Preis')->get();

// Array-Variante
$rows = $db->from('products')->select(['title AS name', 'price'])->get();
Besonderheiten:
  • Mehrfaches Aufrufen von select() ist erlaubt – der letzte Aufruf überschreibt die vorherigen Einstellungen.
  • Wird kein select() verwendet, ist das Verhalten wie bei select('*').
  • Aliasnamen (AS) werden automatisch erkannt (case-insensitive).
  • Felder, die im Datensatz fehlen, werden mit null gefüllt.
Internes Verhalten:
  • Alle ausgewählten Felder werden in $this->select gespeichert.
  • Die Zuordnung von Aliasnamen erfolgt über $this->aliasMap.
  • Beim späteren Aufruf von get() wird die Auswahl über applySelect() umgesetzt.
Beispielausgabe:

[
  {
    "Produktname": "Wasserkocher",
    "Preis": 39.99
  },
  {
    "Produktname": "Toaster",
    "Preis": 29.95
  }
]

🔁 Diese Auswahl beeinflusst die Ausgabe von get() und ist kombinierbar mit where(), orderBy(), limit(), groupBy() usw.


🔎 where()

[Trait: JS_Query]

Die Methode where() filtert die Datensätze anhand definierter Bedingungen. Du kannst mehrere Bedingungen gleichzeitig prüfen und sie logisch mit AND oder OR verknüpfen (Standard: OR).

Jede Bedingung besteht aus einem Array mit drei Elementen: [Feld, Operator, Wert]. Alternativ kannst du eine Bedingung auch mit 'not' negieren.


// Einzelne Bedingung
$db->where([['vendor', '=', 'Aldi']]);

// Mehrere Bedingungen mit AND
$db->where([
  ['vendor', '=', 'Aldi'],
  ['rating', '>=', 4]
], 'AND');

// Negation mit NOT
$db->where([
  ['not', ['rating', '=', 2]],
  ['vendor', '=', 'Lidl']
], 'AND');

// IN-Filter
$db->where([
  ['vendor', 'in', ['Aldi', 'Lidl']],
  ['product', 'not in', 'Toaster, Wasserkocher']
], 'AND');
Unterstützte Operatoren:
  • =, == – Gleichheit
  • != – Ungleichheit
  • >, >=, <, <= – Vergleichsoperatoren
  • like – Textsuche mit Platzhalter %
  • in, not in – Vergleich mit einer Liste (Array oder String)
  • not – Negation einer einzelnen Bedingung
Verknüpfung:
  • Standardmäßig werden Bedingungen mit ODER verknüpft ('OR')
  • Mit dem zweiten Parameter kannst du 'AND' erzwingen
  • Mit $append = true kannst du mehrere where()-Aufrufe kombinieren
Internes Verhalten:
  • Alle Bedingungen werden in $this->filters gespeichert
  • Die Verknüpfung (AND/OR) steht in $this->mergeCondition
  • Beim get() werden alle Filter mit applyFilters() ausgewertet
Beispielausgabe:

[
  {
    "vendor": "Aldi",
    "product": "Wasserkocher",
    "rating": 4
  }
]

🔁 Diese Filterung kann mit select(), orderBy(), groupBy() usw. kombiniert werden.


📦 get()

[Trait: JS_CRUD]

Die Methode get() ist das Herzstück jeder Abfrage in JsonSQL. Sie führt alle gesetzten Bedingungen aus und gibt die Ergebnisse zurück – ähnlich wie ein klassisches SQL-SELECT.

Tabelle wählen

Bevor get() ausgeführt werden kann, muss eine Tabelle gesetzt sein. Dafür stehen drei Varianten zur Verfügung:

  • $db->from('users') – lädt die Tabelle und setzt sie als aktiv. Optional mit autoload = true, um sie direkt zu lesen.
  • $db->setTable('users') – setzt nur die Tabelle ohne sofortige Leseoperation.
  • $db->truncate() – leert die aktuelle Tabelle vollständig (Achtung: destruktiv).
Optional verwendbar: join()

Falls du Daten aus mehreren Tabellen kombinieren möchtest, kannst du join() vor get() in die Kette einfügen:


$db->from('orders')
   ->join('users', 'orders.user_id', '=', 'users.id')
   ->select('orders.id, users.name')
   ->get();
Typischer Anwendungsfall:

// Abfrage mit Filter, Auswahl und Sortierung
$rows = $db->from('products')
           ->where('price', '>', 20)
           ->orderBy('price', 'desc')
           ->select('name AS Produktname, price AS Preis')
           ->limit(5)
           ->get();
Verarbeitungsschritte (intern):
  1. 📁 Tabelle wird geladen (nur bei from())
  2. 🔍 Filter: where()
  3. 🔗 Joins (optional)
  4. 📊 Gruppierung: groupBy()
  5. 🔃 Sortierung: orderBy()
  6. ⏳ Limitierung: limit()
  7. 🎯 Feld-Auswahl: select()
Rückgabe:

Ein Array von assoziativen Arrays – jeder Eintrag entspricht einem Datensatz.


[
  { "Produktname": "Kaffeemaschine", "Preis": 79.90 },
  { "Produktname": "Toaster",        "Preis": 39.99 },
  ...
]
Hinweise:
  • Wenn select() nicht aufgerufen wurde, gibt get() alle Felder zurück.
  • Die Methode verändert keine Daten – sie ist rein lesend.
  • In Kombination mit paginate() enthält die Rückgabe auch Metainformationen zur Seitennavigation.

📌 Intern werden alle Schritte strikt in Reihenfolge ausgeführt. Die Methode get() schließt die Abfrage ab.


❓ exists()

[Trait: JS_CRUD]

Prüft, ob ein bestimmter Datensatz existiert (true/false):


$exists = $db->from('users')->where('email', '=', 'bob@example.com')->exists();
  

🎯 pluck()

  • Parameter:
  • string $column – Der Feldname, der ausgegeben werden soll
  • bool $all = false – Gibt bei true alle Werte zurück, sonst nur den ersten

[Trait: JS_CRUD]

Gibt den Wert eines bestimmten Feldes zurück – entweder vom ersten Datensatz oder von allen.


// Einzelwert (erster Treffer)
$email = $db->from('users')
            ->where('id', '=', 1)
            ->pluck('email');

// Mehrere Werte
$alleEmails = $db->from('users')
                 ->pluck('email', true);
  • 📥 Gibt standardmäßig nur den ersten Wert zurück
  • 🔁 Wenn true als zweiter Parameter gesetzt ist, wird ein Array aller Werte geliefert
  • 💡 Kombinierbar mit where(), orderBy(), limit() etc.

Tipp: Ideal für Dropdowns, Autovervollständigung oder schnelle Lookups!


🥇 first()

[Trait: JS_CRUD]

Gibt den ersten passenden Datensatz einer Abfrage zurück – ideal für gezielte Einzelergebnisse wie Benutzer- oder Detaildaten.


$user = $db->from('users')
           ->where('email', '=', 'alice@example.com')
           ->first();

if ($user) {
    echo "Willkommen zurück, " . $user['name'];
}
  • ✅ Gibt ein array mit den Felddaten zurück
  • 🚫 Gibt null zurück, wenn kein Treffer gefunden wurde
  • ⚡ Intern wird automatisch limit(1) gesetzt – schnell und effizient

Tipp: Kombiniere select(), where() und first() für gezielte Feldabfragen.


🧹 clearTable()

  • Rückgabewert: void – Kein Rückgabewert
  • Parameter: string $tableName – Name der Tabelle, die geleert werden soll

[Trait: JS_TABLES]

Diese Methode leert den Inhalt einer existierenden Tabelle, ohne sie zu löschen oder neu anzulegen. Falls die Tabelle nicht existiert, wird eine Exception geworfen.

clearTable(string \$tableName) ist ideal für gezielte Löschvorgänge bei vorhandenen Tabellen, ohne das Risiko, versehentlich neue Dateien anzulegen. Anders als truncate() wird keine Tabelle erstellt, wenn sie fehlt.

📌 Methodensignatur
public function clearTable(string $tableName): void
📋 Beispiel
$json = new JsonSQL('data');
$json->clearTable('produkte'); // Inhalt der Tabelle 'produkte' wird geleert
✅ Unterschiede zu truncate()
  • clearTable() → leert nur, wenn Tabelle existiert
  • truncate() → leert oder erstellt leere Datei
❗ Fehlerbehandlung
  • Wenn die Tabelle nicht existiert, wird eine Exception mit einer klaren Fehlermeldung geworfen.

☠️ clear()

  • Rückgabewert: void – Kein Rückgabewert
  • Parameter: bool $requireConfirmation – Muss auf true gesetzt werden, um die Aktion zu bestätigen

[Trait: JS_DATBASE]

Warnung: Diese Methode löscht alle Tabellen aus der aktuell gewählten Datenbank unwiderruflich. Sie sollte nur mit Bestätigung aufgerufen werden.

Mit clear(bool \$requireConfirmation) entfernst du sämtliche JSON-Dateien (also Tabellen) aus dem aktuell gesetzten Datenbankverzeichnis. Der Parameter \$requireConfirmation muss explizit auf true gesetzt werden, um versehentliches Löschen zu vermeiden.

📌 Methodensignatur
public function clear(bool $requireConfirmation = false): void
📋 Beispiel
$json = new JsonSQL('data');
$json->clear(true); // Alle Tabellen löschen (nur mit Bestätigung!)
🧠 Hinweis
  • Ohne true als Parameter wird die Methode mit einer Exception abgebrochen.
  • Diese Methode löscht nur die .json-Tabellen, nicht die .system.json-Dateien – sofern du das möchtest, kannst du das intern noch erweitern.

📄 paginate()

Teilt große Ergebnislisten in Seiten auf:


$page = 1;
$limit = 10;
$result = $db->from('users')->paginate($page, $limit);
  

Die Rückgabe enthält Einträge, Gesamtanzahl, Seitenanzahl und mehr.


Datenfelder & system.json

📘 Einführung

In JsonSQL kann jede Tabelle durch eine ergänzende .system.json-Datei um eine strukturierte Felddefinition erweitert werden. Diese Datei steuert automatisch:

  • ⚙️ die Feldtypen (dataType) und ihre Eigenschaften
  • 🛡️ Validierungsregeln wie required, min, max, enum
  • 🔐 Verschlüsselung einzelner Felder mit encrypt
  • ⏱️ automatische Timestamps bei Erstellung und Änderung
  • 🧮 automatisches Hochzählen von Feldern (autoincrement)
  • 🎲 Zufallswerte oder Hashes

Die system.json ist optional, wird jedoch bei komplexeren Datenstrukturen empfohlen, da sie die Validierung und Automatisierung auf Tabellenebene kapselt und die Wartbarkeit erhöht.

JsonSQL lädt diese Konfiguration automatisch beim Setzen der Tabelle mittels setTable() und nutzt sie u. a. bei:

  • insert() – automatische Ergänzung & Prüfung von Feldern
  • update() – Validierung & Timestamp-Aktualisierung
  • analyzeTable() – strukturelle Analyse der Tabellendaten

Die Konfiguration befindet sich standardmäßig in [TABELLE].system.json im selben Verzeichnis wie die Tabelle selbst.


🌐 Globale Optionen

Neben den Feldern selbst kannst du in der system.json-Datei auch globale Optionen für das Verhalten der Tabelle definieren. Diese betreffen z. B. den Umgang mit unbekannten Feldern, die Verschlüsselung oder die Zeitverarbeitung.

Option Typ Beschreibung Standardwert
allowAdditionalFields boolean Erlaubt zusätzliche Felder, die nicht in fields definiert sind true
encryption_key string Optionaler Schlüssel für die Feld-Verschlüsselung (nur für encrypt-Felder notwendig) intern generierter Fallback
timezone string Zeitzone für automatische Timestamps (z. B. UTC, Europe/Berlin) UTC

Du kannst diese Optionen jederzeit mit setSystemOption() ändern oder mit getSystemOption() auslesen.


// Beispiel: Option setzen
$db->setSystemOption('allowAdditionalFields', false);

// Beispiel: Option lesen
$tz = $db->getSystemOption('timezone');

🧩 Feldoptionen

Die Feldoptionen in system.json definieren, wie sich jedes einzelne Feld einer Tabelle verhalten soll – sowohl bei der Speicherung (insert()) als auch bei der Aktualisierung (update()). Diese Metadaten erlauben es, deine Datenstruktur formal zu beschreiben und Prüfungen, Automatisierungen und Schutzmechanismen zentral zu hinterlegen – ohne diese manuell im Code implementieren zu müssen.

JsonSQL nutzt diese Informationen u. a. für:

  • automatische Generierung von Werten (z. B. bei autoincrement, random, timestamp)
  • Validierung von Pflichtfeldern, erlaubten Werten oder Längen
  • Datenverschlüsselung bei sensiblen Informationen wie Passwörtern

Die folgende Tabelle zeigt dir alle unterstützten Feldoptionen mit Beschreibung und Beispielen:

Property Typ Beschreibung Beispiel
dataType string Legt den Datentyp des Feldes fest.
Unterstützte Werte sind z. B. string, integer, float, datetime, boolean, enum.
"integer"
length int Begrenzt die maximale Länge des Feldes (nur für string) 255
precision int Gibt an, auf wie viele Nachkommastellen gerundet wird (nur für float) 2
defaultValue beliebig Wert, der verwendet wird, wenn beim Insert/Update kein Wert übergeben wurde "unbekannt"
required boolean Gibt an, ob das Feld zwingend ausgefüllt werden muss true
unique boolean Stellt sicher, dass dieser Feldwert nur einmal in der gesamten Tabelle vorkommt true
allowNULL boolean Legt fest, ob der Wert explizit null sein darf false
unit string Optionaler Einheitshinweis – z. B. für Anzeigezwecke oder Export "kg", "€"
enumValues array Definiert erlaubte Werte für Felder mit Typ enum ["rot", "grün", "blau"]
min / max int/float Grenzwerte für Zahlenfelder (auch bei Zufallswerten oder Validation) min: 0, max: 100
random boolean Wenn true, wird der Wert automatisch per Zufall (innerhalb min/max) erzeugt true
comment string Dokumentation oder Beschreibung des Feldes – rein informativ "Interne Referenznummer"

Die Feldoptionen können beliebig kombiniert werden – etwa ein Feld mit Typ integer, required, random und einem gültigen Bereich von 1 bis 99. JsonSQL prüft diese Eigenschaften automatisch bei jedem Speichern.

Weitere spezielle Eigenschaften findest du im Abschnitt ⚙️ Auto-Felder, z. B. autoincrement, autohash, auto_create_timestamp oder encrypt.


⚙️ Auto-Felder

JsonSQL unterstützt sogenannte „Auto-Felder“, bei denen bestimmte Werte nicht manuell gesetzt werden müssen, sondern automatisch bei insert() oder update() generiert werden.

Diese Felder sparen Zeit, sorgen für Konsistenz und reduzieren Fehlerquellen – vor allem bei IDs, Timestamps und Sicherheitsthemen.

Feldtyp Beschreibung Beispiel-Konfiguration
autoincrement Zählt bei jedem neuen Datensatz automatisch hoch (z. B. für IDs). Unterstützt autoincrement_value (Startwert) und autoincrement_step.
{
  "id": {
    "dataType": "integer",
    "autoincrement": true,
    "autoincrement_value": 1,
    "autoincrement_step": 1
  }
}
autouuid Erstellt beim Speichern automatisch eine UUIDv4. Ideal für externe Referenzen oder sichere Primärschlüssel.
{
  "uuid": {
    "dataType": "string",
    "autouuid": true
  }
}
autohash Generiert automatisch einen Hash aus einem oder mehreren Feldwerten. Unterstützte Algorithmen: md5, sha1, sha256.
{
  "checksum": {
    "dataType": "string",
    "autohash": true,
    "algorithm": "sha256",
    "length": 64
  }
}
auto_create_timestamp Setzt den aktuellen Zeitstempel bei Erstellung eines Datensatzes. Kann mit format und timezone angepasst werden.
{
  "created_at": {
    "dataType": "datetime",
    "auto_create_timestamp": true,
    "format": "Y-m-d H:i:s",
    "timezone": "UTC"
  }
}
auto_modified_timestamp Aktualisiert sich bei jeder Änderung automatisch. Gleiche Format-Optionen wie bei auto_create_timestamp.
{
  "updated_at": {
    "dataType": "datetime",
    "auto_modified_timestamp": true,
    "format": "Y-m-d H:i:s"
  }
}
encrypt Verschlüsselt das Feld automatisch beim Speichern.
Nur für Felder vom Typ string erlaubt. Entschlüsselung erfolgt intern beim Lesen automatisch.
{
  "password": {
    "dataType": "string",
    "encrypt": true
  }
}
random Generiert bei fehlendem Wert eine Zufallszahl im Bereich minmax. Nur für integer oder float.
{
  "code": {
    "dataType": "integer",
    "random": true,
    "min": 100000,
    "max": 999999
  }
}

Auto-Felder können mit anderen Eigenschaften wie required, defaultValue oder comment kombiniert werden.

Du kannst Auto-Felder bequem über den internen API-Call addFieldDefinition() oder interaktive Tools hinzufügen.


🧪 Validierung

JsonSQL prüft beim insert() und update() automatisch die Felder gegen die in system.json definierten Regeln. Dabei wird sichergestellt, dass Datensätze vollständig, konsistent und im erwarteten Format gespeichert werden.

📌 Unterstützte Validierungsregeln

Feld Beschreibung Beispiel
required Feld darf nicht fehlen oder leer sein
{
  "email": {
    "dataType": "string",
    "required": true
  }
}
min / max Numerische Wertebegrenzung oder Stringlängenprüfung (bei string)
{
  "age": {
    "dataType": "integer",
    "min": 18,
    "max": 99
  }
}
length Erwartete Länge von Strings oder numerischen Feldern
{
  "zip": {
    "dataType": "string",
    "length": 5
  }
}
enumValues Zulässige Werte für ein enum-Feld (als Liste)
{
  "status": {
    "dataType": "enum",
    "enumValues": ["open", "closed", "pending"]
  }
}
allowNULL Erlaubt explizit null als gültigen Wert
{
  "comment": {
    "dataType": "string",
    "allowNULL": true
  }
}
defaultValue Wird verwendet, wenn das Feld leer oder nicht gesetzt ist
{
  "country": {
    "dataType": "string",
    "defaultValue": "Germany"
  }
}

⚠️ Fehlerbehandlung

Wenn ein Feld nicht den Validierungsregeln entspricht, wird der Vorgang mit einer Exception abgebrochen. Dies verhindert inkonsistente oder unvollständige Daten.

Die Prüfung erfolgt intern in validateFieldProperties() und validateSystemFieldProperties() und gilt sowohl für neue als auch für geänderte Felder.

🔍 Tipps

  • Wenn required gesetzt ist, muss entweder ein Wert übergeben oder ein defaultValue angegeben werden.
  • enum ist besonders nützlich für Status-Felder oder feste Auswahlwerte.
  • Für strukturierte Prüfung von Tabellen kannst du analyzeTable() oder analyzeSystemTable() verwenden.

🔎 Analyse

JsonSQL bietet eingebaute Analysefunktionen, um deine Tabellenstruktur und die zugehörige system.json-Konfiguration auf Inkonsistenzen zu überprüfen. Dies ist besonders hilfreich zur Qualitätssicherung und Fehlersuche.


📊 analyzeTable() – Daten prüfen

Diese Methode analysiert die vorhandenen Datensätze einer Tabelle und prüft sie gegen die in der system.json definierten Felder. Sie erkennt:

  • fehlende Pflichtfelder (wenn required: true)
  • ⚠️ zusätzliche Felder, die nicht in system.json definiert sind

Optional kann auch geprüft werden, ob zusätzliche Felder erlaubt sind oder nicht (abhängig von allowAdditionalFields).

Beispiel:


$errors = $db->analyzeTable();
foreach ($errors as $issue) {
  echo "Zeile {$issue['row']} hat Probleme:\n";
  echo "- Fehlend: " . implode(', ', $issue['missing']) . "\n";
  echo "- Überflüssig: " . implode(', ', $issue['extra']) . "\n";
}

Beispielausgabe:


Zeile 3 hat Probleme:
- Fehlend: email
- Überflüssig: debug_note

🧠 analyzeSystemTable() – system.json prüfen

Diese Methode prüft die system.json einer Tabelle auf fehlerhafte Felddefinitionen. Dabei wird analysiert:

  • 🧨 Ungültige dataType-Werte (z. B. Tippfehler wie "datim")
  • 🚫 Nicht erlaubte Feldoptionen (z. B. foobar statt defaultValue)

Beispiel:


$report = $db->analyzeSystemTable();
print_r($report);

Beispielausgabe:


[
  "invalidTypes" => [
    ["field" => "birthday", "dataType" => "datim"]
  ],
  "invalidProperties" => [
    ["field" => "email", "property" => "foobar"]
  ]
]

So erkennst du auf einen Blick, ob Konfigurationsfehler in der system.json vorliegen.


🔁 Einsatzmöglichkeiten

  • 🧪 Vor dem Import größerer Datenmengen
  • 🧼 Nach dem Hinzufügen neuer Felder zur Validierung
  • 📋 Zur strukturellen Kontrolle bei dynamischen Datenquellen

Tipp: Kombiniere getTableInfo() mit analyzeTable(), um vollständige Einblicke in Struktur, Datenmenge, Felder und Inkonsistenzen zu erhalten.


🔤 Datentyp: string

Der Datentyp string ist der meistverwendete Typ für Textinhalte wie Namen, E-Mails, Adressen, Notizen oder einfache Texteingaben. Felder mit diesem Typ akzeptieren beliebige Zeichenfolgen, können aber zusätzlich eingeschränkt oder geschützt werden.

🔧 Unterstützte Optionen

Option Beschreibung Beispiel
length Erwartete exakte Zeichenanzahl "length": 5
min Minimale Länge des Textes "min": 3
max Maximale Länge des Textes "max": 50
required Pflichtfeld (darf nicht leer sein) "required": true
defaultValue Wird verwendet, wenn kein Wert gesetzt wurde "defaultValue": "N/A"
encrypt Speichert den Wert verschlüsselt (AES-256) "encrypt": true
allowNULL Erlaubt explizit den Wert null "allowNULL": true

🧪 Validierung

  • Wird auf Mindest- und Maximallänge geprüft (wenn gesetzt)
  • Leere Strings "" gelten als "nicht gesetzt", wenn required: true
  • Ein defaultValue wird eingesetzt, wenn der Wert leer oder nicht vorhanden ist
  • Bei encrypt: true erfolgt die Verschlüsselung automatisch vor dem Speichern

📦 Beispieldefinition


"email": {
  "dataType": "string",
  "required": true,
  "min": 5,
  "max": 100,
  "defaultValue": "unbekannt@example.com",
  "encrypt": true
}

📌 Besonderheiten

  • Feld wird intern immer als string behandelt – auch wenn numerisch (z. B. Postleitzahl)
  • In Kombination mit encrypt besonders geeignet für sensible Daten wie Passwörter, IBAN, API-Keys

🔢 Datentyp: integer

Der integer-Typ ist ideal für ganzzahlige Werte – z. B. IDs, Mengen, Altersangaben oder Zähler. JsonSQL erkennt, ob eine gültige Ganzzahl eingegeben wurde, und kann diese bei Bedarf automatisch generieren oder prüfen.

🔧 Unterstützte Optionen

Option Beschreibung Beispiel
min Minimal erlaubter Wert "min": 0
max Maximal erlaubter Wert "max": 1000
required Feld muss gesetzt sein "required": true
defaultValue Standardwert, falls keiner angegeben "defaultValue": 1
autoincrement Wert wird automatisch hochgezählt "autoincrement": true
autoincrement_value Startwert des Zählers "autoincrement_value": 100
autoincrement_step Schrittweite beim Hochzählen "autoincrement_step": 5
random Zufallswert generieren (zwischen min und max) "random": true
allowNULL Erlaubt den Wert null "allowNULL": true

🧪 Validierung

  • Wird auf Ganzzahligkeit geprüft (keine Kommawerte oder Strings erlaubt)
  • Bei min/max wird der Zahlenbereich kontrolliert
  • Bei random: true wird der Wert zufällig zwischen min und max gesetzt
  • Wenn autoincrement aktiv ist, wird der Zählerwert automatisch verwendet

📦 Beispieldefinition


"counter": {
  "dataType": "integer",
  "autoincrement": true,
  "autoincrement_value": 1000,
  "autoincrement_step": 10
}

📌 Besonderheiten

  • Sehr gut geeignet für IDs, Artikelnummern, Positionen oder sortierbare Reihenfolgen
  • autoincrement kann für jede Tabelle separat gesteuert werden
  • Du kannst setAutoincrementValue() verwenden, um den Zähler manuell zu setzen

🌊 Datentyp: float

Der float-Typ dient zur Speicherung von Gleitkommazahlen mit Dezimalstellen, z. B. Gewichte, Preise, Temperaturwerte oder Prozentangaben. Im Gegensatz zu integer erlaubt dieser Typ Nachkommastellen und kann sehr große oder sehr kleine Werte speichern.

🔧 Unterstützte Optionen

Option Beschreibung Beispiel
min Minimaler Wert "min": 0.0
max Maximaler Wert "max": 100.5
precision Anzahl der Dezimalstellen "precision": 2
required Pflichtfeld "required": true
defaultValue Standardwert bei leerem Feld "defaultValue": 0.0
random Zufallswert (zwischen min und max) "random": true
allowNULL Erlaubt null als gültigen Wert "allowNULL": true

🧪 Validierung

  • Wert muss numerisch und als Fließkommazahl interpretierbar sein
  • min und max definieren den erlaubten Wertebereich
  • Bei aktivierter random-Option wird ein zufälliger Float generiert
  • precision rundet den Wert automatisch auf die gewünschte Nachkommastelle

📦 Beispieldefinition


"price": {
  "dataType": "float",
  "min": 0.0,
  "max": 9999.99,
  "precision": 2,
  "defaultValue": 0.0,
  "required": true
}

📌 Besonderheiten

  • Intern wird der Wert in PHP als float gecastet – z. B. (float) $value
  • Bei precision = 2 wird 4.5678 zu 4.57
  • Optimal für Geldbeträge, Berechnungsfelder oder wissenschaftliche Messwerte

☑️ Datentyp: boolean

Der boolean-Typ wird verwendet, um logische Zustände zu speichern: true (wahr) oder false (falsch). Typisch z. B. für Schalter, Aktiv-Flags, Berechtigungen, Bestätigungen oder Statusfelder.

🔧 Unterstützte Optionen

Option Beschreibung Beispiel
defaultValue Standardwert (true oder false) "defaultValue": false
required Pflichtfeld "required": true
allowNULL Erlaubt explizit den Wert null "allowNULL": true

🎯 Zulässige Werte

  • true oder false (als Boolean-Wert)
  • 1 / 0 (werden zu true/false konvertiert)
  • "true" / "false" (werden erkannt und entsprechend umgewandelt)

🧪 Validierung

  • Nur die oben genannten Werte sind gültig
  • Ungültige Werte (z. B. "yes", "no", "vielleicht") führen zu einer Fehlermeldung
  • Standardwert wird gesetzt, wenn kein gültiger Wert angegeben und defaultValue definiert ist

📦 Beispieldefinition


"isActive": {
  "dataType": "boolean",
  "defaultValue": true,
  "required": true
}

📌 Besonderheiten

  • Ideal für Checkboxen, Statusfelder, Aktivierungsflags oder Ja/Nein-Entscheidungen
  • Intern wird der Wert automatisch zu true/false gecastet

📅🕒 Datentyp: datetime

Der datetime-Typ speichert Datum und Uhrzeit in einem einheitlichen Format. Er eignet sich für Felder wie created_at, updated_at, Terminangaben, Zeitpunkte von Events oder Logeinträge.

🔧 Unterstützte Optionen

Option Beschreibung Beispiel
auto_create_timestamp setzt automatisch bei Erstellung "auto_create_timestamp": true
auto_modified_timestamp aktualisiert automatisch bei Änderung "auto_modified_timestamp": true
format Datumsformat (PHP-kompatibel) "format": "Y-m-d H:i:s"
timezone Zeitzone (z. B. UTC, Europe/Berlin) "timezone": "UTC"
defaultValue Standardwert (z. B. "now") "defaultValue": "now"
required Pflichtfeld "required": true

🧪 Validierung

  • Wert muss ein gültiges Datum/Uhrzeit im angegebenen format sein
  • Bei defaultValue: "now" wird der aktuelle Zeitstempel eingefügt
  • Automatik-Felder wie auto_create_timestamp oder auto_modified_timestamp ignorieren benutzerdefinierte Eingaben

📦 Beispieldefinition


"created_at": {
  "dataType": "datetime",
  "auto_create_timestamp": true,
  "format": "Y-m-d H:i:s",
  "timezone": "UTC",
  "comment": "Setzt sich beim Insert automatisch"
},
"updated_at": {
  "dataType": "datetime",
  "auto_modified_timestamp": true
}

📌 Besonderheiten

  • Ideal für Logging, automatische Zeitstempel, zeitgesteuerte Prozesse
  • Format kann an lokale Systeme angepasst werden (z. B. d.m.Y H:i für deutsche Darstellung)
  • timezone wirkt nur bei automatischer Timestamp-Erstellung

📅 Datentyp: date

Der date-Typ speichert ausschließlich ein Datum – ohne Uhrzeit. Er eignet sich für Geburtsdaten, Fälligkeiten, Gültigkeiten oder historische Zeitpunkte.

🔧 Unterstützte Optionen

Option Beschreibung Beispiel
format Datumsformat nach PHP-Syntax "format": "Y-m-d" (Standard)
defaultValue Standarddatum (z. B. "now", "2025-01-01") "defaultValue": "now"
required Pflichtfeld "required": true
allowNULL Erlaubt null als gültigen Wert "allowNULL": true

🎯 Zulässige Formate

  • Y-m-d (Standard: 2025-04-18)
  • Beliebige PHP-Formate wie d.m.Y, m/d/Y, etc.

🧪 Validierung

  • Das Datum muss dem definierten format entsprechen
  • Bei "defaultValue": "now" wird das heutige Datum automatisch eingesetzt
  • Fehlerhafte Eingaben wie "2025-99-99" werden erkannt und abgelehnt

📦 Beispieldefinition


"birthdate": {
  "dataType": "date",
  "format": "Y-m-d",
  "required": true
}

📌 Besonderheiten

  • Ohne Uhrzeit – ideal für klare Kalendertage
  • Automatische Verarbeitung bei insert() möglich (mit "now")
  • Im Gegensatz zu datetime kein Zeitanteil enthalten

🕒 Datentyp: time

Der time-Typ speichert ausschließlich Uhrzeiten ohne Datum. Ideal für Öffnungszeiten, Startzeiten, Erinnerungen oder Zeitpunkte innerhalb eines Tages.

🔧 Unterstützte Optionen

Option Beschreibung Beispiel
format Uhrzeit-Format nach PHP-Notation "format": "H:i:s" (Standard)
defaultValue Standardzeit (z. B. "now" oder "08:00:00") "defaultValue": "now"
required Pflichtfeld "required": true
allowNULL null ist erlaubt "allowNULL": true

🎯 Gültige Uhrzeitformate

  • H:i:s (24h – z. B. 15:45:00)
  • H:i (ohne Sekunden – z. B. 09:30)
  • g:i A (12h – z. B. 5:00 PM)

🧪 Validierung

  • Uhrzeit muss dem angegebenen format entsprechen
  • "defaultValue": "now" setzt aktuelle Uhrzeit (Serverzeit)
  • Ungültige Zeiten wie "25:99" oder "ab:cd" werden abgewiesen

📦 Beispieldefinition


"open_at": {
  "dataType": "time",
  "format": "H:i",
  "defaultValue": "08:00"
}

📌 Besonderheiten

  • Kann mit date oder datetime kombiniert werden
  • Perfekt für Zeitfenster (z. B. von/bis)
  • Unterstützt sowohl 24h- als auch 12h-Formate (abhängig vom Formatstring)

Weiter mit: 📚 Datentyp: enum


📚 Datentyp: enum

Der enum-Typ erlaubt ausschließlich vordefinierte Werte, ähnlich wie Auswahllisten oder Drop-Downs. Er ist ideal für feste Zustände wie Rollen, Kategorien, Farben oder Ja/Nein-Logiken mit Klartext.

🔧 Unterstützte Optionen

Option Beschreibung Beispiel
enumValues Liste erlaubter Werte (Pflichtfeld) "enumValues": ["active", "inactive", "pending"]
defaultValue Voreinstellung, wenn kein Wert übergeben wurde "defaultValue": "pending"
required Pflichtfeld – darf nicht leer sein "required": true
allowNULL Erlaubt null als gültigen Wert "allowNULL": true

🧪 Validierung

  • Der eingegebene Wert muss exakt einem der enumValues entsprechen
  • Groß-/Kleinschreibung wird beachtet (case-sensitive)
  • Ungültige Eingaben werden automatisch abgelehnt

📦 Beispieldefinition


"status": {
  "dataType": "enum",
  "enumValues": ["open", "closed", "in_progress"],
  "defaultValue": "open",
  "required": true
}

📌 Besonderheiten

  • Pflicht zur Angabe der gültigen enumValues
  • Optimal für Drop-Downs, Filter und Statusanzeige
  • Standardwerte wie defaultValue vereinfachen insert()-Aufrufe
  • Kann mit required kombiniert werden

🎉 Das war die Übersicht aller unterstützten Datentypen in JsonSQL!

Filterlogik mit where()

Mit where() kannst du gezielt Datensätze filtern. JsonSQL unterstützt eine Vielzahl an Operatoren, auch in Kombination. Du kannst einfache Vergleiche durchführen oder komplexe Bedingungen mit verschachtelten Feldern und Filtergruppen bauen.

🔣 Unterstützte Operatoren

Standardmäßig stehen dir diese Operatoren zur Verfügung:

  • = (gleich)
  • != (ungleich)
  • >, >=, <, <=
  • in, not in (Array-Vergleich)
  • like (enthält Teilstring, Case-insensitiv)
  • between (zwischen zwei Werten)

// Benutzer mit Alter > 30
$db->from('users')->where('age', '>', 30)->get();

// Benutzer mit Namen in Liste
$db->where('name', 'in', ['Alice', 'Bob']);

// Email enthält "gmail"
$db->where('email', 'like', 'gmail');
  

🔗 Kombinierte Bedingungen (and / or)

Mehrere Filter kannst du mit andWhere() oder orWhere() kombinieren:


$db->from('users')
   ->where('age', '>', 30)
   ->andWhere('status', '=', 'active')
   ->get();

$db->orWhere('name', '=', 'Alice')
   ->orWhere('name', '=', 'Bob');
  

🪆 Nested-Felder und Pfadfilter

Du kannst auch auf verschachtelte Felder zugreifen, z. B. bei Objekten oder Arrays innerhalb eines Datensatzes:


// Greife auf verschachteltes Feld zu
$db->where('address.city', '=', 'Berlin');

// Oder in Arrays mit Index
$db->where('roles.0', '=', 'admin');
  

🧩 Filtergruppen

Du kannst auch mehrere Bedingungen gruppieren und so komplexere Logik umsetzen. Dafür nutzt du Arrays als Eingabe:


$db->where([
  ['status', '=', 'active'],
  ['age', '>', 30]
]);

$db->orWhere([
  ['country', '=', 'DE'],
  ['country', '=', 'AT']
]);
  

Die Filterlogik ist flexibel, performant und erweiterbar – ideal für komplexe Abfragen auf JSON-Basis. Weitere Filterfunktionen wie groupBy(), orderBy() und limit() werden in separaten Abschnitten behandelt.

Aggregation & Statistik

JsonSQL unterstützt eine Vielzahl an Aggregatfunktionen, mit denen du deine Daten gruppieren, zählen, zusammenfassen oder statistisch analysieren kannst. Diese Funktionen sind ideal für Auswertungen, Dashboards oder Reports.

📊 groupBy()

Gruppiert die Datensätze nach einem bestimmten Feld und erlaubt dir, Aggregatfunktionen innerhalb dieser Gruppen anzuwenden.


// Anzahl Nutzer pro Land
$db->from('users')
   ->groupBy('country')
   ->count();
  

➕ Aggregatfunktionen

Folgende Funktionen stehen dir zur Verfügung:

  • count() – Anzahl der Einträge
  • sum('feld') – Summe eines Feldes
  • avg('feld') – Durchschnitt
  • min('feld'), max('feld')
  • median('feld')
  • mode('feld') – häufigster Wert
  • stddev('feld'), variance('feld')
  • range('feld') – Spanne zwischen Min und Max

// Gesamtsumme aller Bestellungen
$total = $db->from('orders')->sum('amount');

// Durchschnittsalter aller Nutzer
$avg = $db->from('users')->avg('age');
  

📈 stats() – kombinierte Übersicht

Mit stats('feld') bekommst du alle wichtigen Kennzahlen in einem Aufruf:


$stats = $db->from('users')->stats('age');
/* Gibt zurück:
[
  'count' => 100,
  'sum' => 2300,
  'avg' => 23,
  'min' => 18,
  'max' => 65,
  'median' => 22,
  'mode' => 21,
  'stddev' => 4.2,
  'variance' => 17.64,
  'range' => 47
]
*/
  

Du kannst stats() auch mit groupBy() kombinieren:


// Statistik pro Land
$statistik = $db->from('users')->groupBy('country')->stats('age');
  

Mit diesen Tools kannst du deine Daten schnell analysieren – direkt aus JSON-Dateien heraus, ganz ohne klassische Datenbank.

Joins & Beziehungen

JsonSQL unterstützt SQL-ähnliche Joins, um Daten aus mehreren Tabellen zu kombinieren. Dabei kannst du klassische inner, left, right oder full Joins nutzen – alles direkt auf JSON-Basis.

🔗 join()-Logik

Die Methode join() erlaubt das Verknüpfen zweier Tabellen anhand gemeinsamer Felder:


$rows = $db->from('orders')
  ->join('users', 'user_id', '=', 'id', 'left')
  ->get();
  

Parameter:

  • Tabelle: Die zweite Tabelle, z. B. users
  • Feld 1: Feld aus der Haupttabelle
  • Operator: Meist =
  • Feld 2: Feld aus der zweiten Tabelle
  • Typ: inner, left, right, full

🔁 n:m-Beziehungen über Zwischentabellen

Für viele-zu-viele-Beziehungen empfiehlt sich eine Zwischentabelle:


Tabellen:
- products.json
- tags.json
- product_tags.json (Felder: product_id, tag_id)
  

Beispiel:


$db->from('product_tags')
   ->join('products', 'product_id', '=', 'id')
   ->join('tags', 'tag_id', '=', 'id')
   ->get();
  

So erhältst du kombinierte Informationen aus allen drei Tabellen.

✅ Best Practices

  • Nutze eindeutige IDs für Relationen
  • Halte Relationen schlank (keine riesigen JSON-Objekte einbetten)
  • Vermeide Duplikate durch gute Datenmodellierung
  • Trenne Stammdaten (z. B. Produkte) und Meta-Relationen (z. B. Kategorien)
  • Nutze pluck() oder groupBy() für zusammengefasste Daten

🚀 Live-Demo

Joins sind ein starkes Werkzeug, um deine JSON-Daten strukturiert zu verbinden – fast wie in echten relationalen Datenbanken.

MySQL-Export

JsonSQL bietet die Möglichkeit, deine JSON-Tabellen samt system.json-Definitionen in gültige MySQL CREATE TABLE-Anweisungen zu exportieren. Das ist besonders praktisch, wenn du bestehende Daten in eine klassische SQL-Datenbank migrieren oder externe Tools anbinden möchtest.

🚀 Funktionen im Überblick
  • ExportMySQLCreate($table): Gibt ein CREATE TABLE-Statement für eine bestimmte Tabelle zurück.
  • ExportMySQLData($table): Gibt alle INSERT INTO-Statements der Datensätze einer Tabelle zurück.
  • ExportMySQLFull($table): Kombiniert CREATE und INSERT für eine Tabelle.
  • ExportMySQLCreateAll(): Gibt CREATE-Statements für alle vorhandenen Tabellen zurück.
  • ExportMySQLDataAll(): Gibt INSERTs für alle Tabellen zurück.
  • ExportMySQLFullAll(): Gibt einen vollständigen Dump (Struktur + Daten) für alle Tabellen zurück.

Du kannst die Funktionen direkt im Code verwenden – oder bequem per URL-Parameter auslösen:

🧭 Beispiele für URL-Aufrufe
  • ?table=students → Nur Struktur (CREATE)
  • ?table=students&data=1 → Nur Daten (INSERTs)
  • ?table=students&full=1Komplette Tabelle (CREATE + INSERT)
  • ?all=1&create=1Alle CREATE-Statements
  • ?all=1&data=1Alle INSERTs
  • ?all=1&full=1Komplettes SQL-Dump (für alle Tabellen)
🧪 Beispielausgabe

CREATE TABLE `students` (
  `id` INT AUTO_INCREMENT PRIMARY KEY,
  `name` VARCHAR(255),
  `email` VARCHAR(255),
  `created_at` DATETIME
);

INSERT INTO `students` (`id`, `name`, `email`, `created_at`) VALUES
(1, 'Anna Beispiel', 'anna@example.com', '2024-10-03 14:00:00'),
(2, 'Bert Nutzer', 'bert@example.com', '2024-10-03 14:10:00');
  
📦 Export in der Demo nutzen

In der n:m-Demo /demos/nm_students/ kannst du dir die MySQL-Definition jeder Tabelle direkt per Button anzeigen lassen – inkl. Struktur- und Datendump.

🔒 Hinweis: Der Export funktioniert nur für Tabellen mit einer vorhandenen .system.json-Datei, da hier die Felddefinitionen und Datentypen festgelegt sind.

Extras & Tools

JsonSQL bietet eine Reihe nützlicher Zusatzfunktionen für Entwickler, Power-User und Admins. Hier findest du praktische Tools wie Import/Export, Backupfunktionen, Locking-Mechanismen und eine einfache SQL-Parser-Schnittstelle.

📤 import() & 📥 export()

Du kannst Tabellen oder ganze Datenbanken als JSON-Dateien importieren oder exportieren – z. B. für Backups oder Migrationszwecke:


// Ganze Tabelle exportieren
$data = $db->from('users')->export();

// Importieren
$db->from('users')->import($data);
  

🔒 Locking & paralleler Zugriff

JsonSQL arbeitet mit Dateisperren, um gleichzeitige Schreibzugriffe abzusichern. Beim Öffnen einer Tabelle wird automatisch ein exklusiver flock() verwendet. Damit ist auch Multiuser-Zugriff auf dem gleichen Server möglich.

Tipps:

  • Immer get() oder save() korrekt abschließen
  • Keine Dauerprozesse mit blockierenden Operationen!

🗂️ Backupstrategien

Backups können automatisch oder manuell erfolgen. Aktiviere die Option enableBackups(true), um bei jedem Speichern eine Kopie in /backups abzulegen:


$db->enableBackups(true);
  

Backups werden automatisch mit Zeitstempel versehen und in einem separaten Unterordner abgelegt.

📝 SQL-Parser mit query()

Mit query() kannst du einfache SQL-Befehle ausführen, die intern auf JsonSQL gemappt werden. Unterstützt werden aktuell:

  • SELECT ... FROM ... WHERE ...
  • INSERT INTO ...
  • UPDATE ... SET ...
  • DELETE FROM ...

$db->query("SELECT * FROM users WHERE age > 18");
  

Ideal für einfache API-Schnittstellen oder SQL-ähnliche Skripte.

🐞 Logging & Debugging (FancyDumpVar)

Für tieferen Einblick in die Funktionsweise kannst du das Tool FancyDumpVar nutzen. Es visualisiert interne Objekte, Status und Rückgaben direkt im Browser:


$debugger->addInfoText('Datenbankobjekt');
$debugger->dump($db);

$debugger->addInfoText('Letzte Einträge');
$debugger->dump($rows);
  

FancyDumpVar ist ideal bei der Plugin-Entwicklung, für Analysezwecke oder zum Nachvollziehen von komplexeren Abläufen.

Erweiterung & eigene Module

JsonSQL ist modular aufgebaut. Du kannst eigene Module erstellen, um die Funktionalität zu erweitern oder Speziallogik für dein Projekt einzubinden – ganz ohne die Hauptklasse zu verändern.

🧩 Neue Module erstellen & einbinden

Lege einfach eine neue Datei im src/-Verzeichnis an, z. B. JS_CustomDemo.php. Die Datei muss eine Trait-Definition enthalten, die dann in JsonSQL.php eingebunden wird:

// Datei: src/JS_CustomDemo.php
trait JS_CustomDemo {
  public function sayHello($name) {
    return "Hallo, $name!";
  }
}

Danach fügst du die Datei in JsonSQL.php ein:

require_once __DIR__ . '/JS_CustomDemo.php';
class JsonSQL {
  use JS_CustomDemo;
  // ...weitere Module...
}

🧱 Struktur & Best Practices

  • Jedes Modul als JS_*.php benennen
  • Immer einen trait verwenden
  • Methoden sprechend und eindeutig benennen
  • Keine direkten echo-Ausgaben in Modulen – lieber Rückgabewerte verwenden
  • Verwende interne Methoden wie $this->load() oder $this->save(), falls du mit Tabellen arbeitest

📦 Beispiele für eigene Module

Einige Beispielmodule findest du in den Demos:

  • JS_Export.php – Export/Import von JSON-Daten
  • JS_SQLParser.php – SQL-kompatibler Query-Parser
  • JS_System.php – Automatische Felder und system.json-Regeln
  • JS_CustomUUID.php – eigenes Modul zur UUID-Erzeugung

🚀 Demo: Custom Modul

Mit dieser modularen Struktur kannst du JsonSQL beliebig erweitern – ideal für eigene Projekte, Frameworks oder spezialisierte Tools.

API-Referenz

Die folgende API-Referenz listet alle öffentlichen Methoden der JsonSQL-Klasse mit Signatur, Beschreibung, Parametern und Rückgabewerten auf. Sie eignet sich als Nachschlagewerk für Entwickler.

📥 insert()

Beschreibung: Fügt einen oder mehrere Datensätze in die aktive Tabelle ein.

insert(array|array[] $data): array
  • $data: Einzelnes Array oder Array von Arrays mit Feldern und Werten

Rückgabe: Array mit eingefügten Einträgen (inkl. Auto-Felder)

🛠️ update()

Beschreibung: Aktualisiert Einträge gemäß Filterkriterien.

update(array $values): int
  • $values: Felder und neue Werte

Rückgabe: Anzahl der aktualisierten Datensätze

🗑️ delete()

Beschreibung: Löscht Einträge gemäß aktueller Filterung.

delete(): int

Rückgabe: Anzahl der gelöschten Einträge

🔎 get()

Beschreibung: Führt die aktuelle Abfrage aus und gibt das Ergebnis zurück.

get(): array

Rückgabe: Liste der Datensätze (ggf. gefiltert, sortiert etc.)

🔍 where()

Beschreibung: Fügt eine Filterbedingung hinzu.

where(string $field, string $operator, mixed $value): self

🔗 join()

Beschreibung: Verknüpft eine weitere Tabelle mit der aktuellen via Join.

join(string $table, string $field1, string $operator, string $field2, string $type = 'inner'): self

🎯 pluck()

Beschreibung: Gibt eine Spalte als flaches Array zurück.

pluck(string $field): array

🥇 first()

Beschreibung: Gibt das erste Ergebnis der Abfrage zurück.

first(): ?array

♻️ clear()

Beschreibung: Löscht alle Datensätze in der aktuellen Tabelle.

clear(): bool

📄 paginate()

Beschreibung: Gibt eine paginierte Liste mit Meta-Daten zurück.

paginate(int $page, int $limit): array

📊 stats()

Beschreibung: Gibt Statistikwerte zu einem Feld zurück.

stats(string $field): array

📝 query()

Beschreibung: Führt einen einfachen SQL-Befehl aus.

query(string $sql): mixed

Weitere Hilfsfunktionen wie use(), setTable(), enableBackups(), enableTrashMode() usw. findest du in den entsprechenden Abschnitten der Dokumentation.

Über den Autor

Mein Name ist Johannes Teitge, ich bin 58 Jahre alt und habe Jahrzehnte als Informatiker gearbeitet – in unterschiedlichsten Projekten, mit Herzblut für sauberen Code, pragmatische Lösungen und flexible Tools.

JsonSQL ist ein rein privat entwickeltes Projekt, entstanden aus der Idee, strukturierte Daten einfach und ohne klassische Datenbank handhabbar zu machen – ideal für kleine Web-Apps, Admin-Tools, Offline-Anwendungen oder embedded Systeme.

Lizenz & Verwendung

Die Nutzung erfolgt unter einer erweiterten MIT-Lizenz – mit einer einzigen Bedingung:

Mein Name als Urheber (Johannes Teitge) muss im Quelltext oder in der Dokumentation erhalten bleiben.

Unterstützen mit Kaffee?

Ich bin leidenschaftlicher Hobby-Barista – wer mir eine Freude machen will, darf mir gern ein Päckchen richtig guter Kaffeebohnen schicken ☕️😊

Johannes Teitge
Schloßstraße 88
78259 Mühlhausen-Ehingen
Deutschland

Feedback, Bugs & Grüße

Ich freue mich über jede Art von Rückmeldung, Verbesserungsvorschläge, Bugmeldungen oder nette Worte. Einfach eine Mail an:

johannes@teitge.de

Danke fürs Lesen – und viel Freude beim Nutzen und Weiterentwickeln von JsonSQL! 🛠️📂

JsonSQL Logo

JsonSQL Library

⏱️ Laufzeit: 1.13 ms

Developer

Johannes Teitge

Mail: johannes@teitge.de

www: teitge.de

© 2025 JsonSQL – Made with ☕ by Johannes Teitge