std.db.sqlite
SQLite3-Binding via FFI (libsqlite3.so.0). Alle Verbindungs- und Statement-Handles werden als int64-Pointer dargestellt. Das API folgt dem Prepared-Statement-Muster: SQLiteStmtPrepare → Bind → SQLiteStmtStep → Column-Accessoren → SQLiteStmtFinalize.
→ Standard Library · std.db.postgres · std.db.mysql
Konstanten
Rückgabecodes
| Konstante | Wert | Beschreibung |
|---|---|---|
SQLITE_OK | 0 | Erfolg |
SQLITE_ERROR | 1 | Allgemeiner Fehler |
SQLITE_BUSY | 5 | Datenbank ist gesperrt |
SQLITE_NOTFOUND | 12 | Nicht gefunden |
SQLITE_CONSTRAINT | 19 | Constraint-Verletzung (UNIQUE, NOT NULL …) |
SQLITE_MISUSE | 21 | Falsche Verwendung der API |
SQLITE_NOMEM | 7 | Kein Speicher verfügbar |
SQLITE_ROW | 100 | SQLiteStmtStep liefert eine Zeile |
SQLITE_DONE | 101 | SQLiteStmtStep hat alle Zeilen verarbeitet |
Spalten-Typkodes
| Konstante | Wert | SQLite-Typ |
|---|---|---|
SQLITE_INTEGER | 1 | Ganzzahl |
SQLITE_FLOAT | 2 | Gleitkommazahl |
SQLITE_TEXT | 3 | Text |
SQLITE_BLOB | 4 | Binärdaten |
SQLITE_NULL | 5 | NULL |
Destruktor-Sentinels
| Konstante | Wert | Beschreibung |
|---|---|---|
SQLITE_STATIC | 0 | SQLite kopiert die Daten nicht — Puffer muss bis Step/Reset gültig bleiben |
SQLITE_TRANSIENT | -1 | SQLite macht eine interne Kopie sofort |
Typen
SQLiteDB (24 Bytes)
Verbindungs-Handle. Immer über SQLiteOpen erstellen und über SQLiteClose freigeben.
SQLiteStmt (24 Bytes)
Prepared-Statement-Handle. Immer über SQLiteStmtPrepare erstellen und über SQLiteStmtFinalize freigeben.
Funktionen
Verbindung
Funktionen für Verbindungsaufbau und -verwaltung:
| Signatur | Beschreibung |
|---|---|
SQLiteOpen(path: pchar): int64 | Öffnet oder erstellt eine SQLite-Datenbank. „:memory:„ für In-Memory-DB. Gibt SQLiteDB-Pointer zurück; 0 bei Fehler |
SQLiteClose(db: int64): void | Schließt Verbindung und gibt SQLiteDB-Speicher frei |
SQLiteExec(db: int64, sql: pchar): bool | Führt SQL ohne Ergebnismenge aus (CREATE TABLE, INSERT ohne Bind, PRAGMA …). Gibt true bei Erfolg |
SQLiteExecParam(db: int64, sql: pchar, params: int64, nparams: int64): bool | Führt parametrisiertes SQL mit String-Parametern aus. params: Zeiger auf Array von nparams pchar-Pointern |
SQLiteErrmsg(db: int64): pchar | Fehlermeldung der letzten Operation |
SQLiteErrno(db: int64): int64 | Fehlercode der letzten Operation |
Prepared Statements
Funktionen für Prepared Statements:
| Signatur | Beschreibung |
|---|---|
SQLiteStmtPrepare(db: int64, sql: pchar): int64 | Kompiliert SQL zu einem Prepared Statement. Gibt SQLiteStmt-Pointer zurück; 0 bei Fehler |
SQLiteStmtStep(stmt: int64): int64 | Führt einen Schritt aus. Gibt SQLITE_ROW (Zeile verfügbar), SQLITE_DONE (fertig) oder Fehlercode zurück |
SQLiteStmtReset(stmt: int64): void | Setzt Statement zurück — Bindings bleiben erhalten, für Re-Execution mit neuen Werten |
SQLiteStmtFinalize(stmt: int64): void | Gibt Statement-Speicher frei |
SQLiteClearBindings(stmt: int64): void | Setzt alle Bindings auf NULL zurück |
Parameter-Binding (1-basierter Index)
| Signatur | Beschreibung |
|---|---|
SQLiteBindInt(stmt: int64, i: int64, v: int64): bool | Bindet int64 an Parameter i |
SQLiteBindFloat(stmt: int64, i: int64, v: f64): bool | Bindet f64 an Parameter i |
SQLiteBindStr(stmt: int64, i: int64, v: pchar): bool | Bindet null-terminierten String an Parameter i (SQLITE_STATIC — Puffer bis Step/Reset gültig halten) |
SQLiteBindNull(stmt: int64, i: int64): bool | Bindet NULL an Parameter i |
SQLiteBindBlob(stmt: int64, i: int64, ptr: int64, len: int64): bool | Bindet Binärdaten an Parameter i (SQLITE_STATIC) |
Column-Accessoren (0-basierter Index)
| Signatur | Beschreibung |
|---|---|
SQLiteColumnInt(stmt: int64, i: int64): int64 | INTEGER-Spalte lesen |
SQLiteColumnFloat(stmt: int64, i: int64): f64 | REAL-Spalte lesen |
SQLiteColumnText(stmt: int64, i: int64): pchar | TEXT-Spalte lesen — Pointer bis zum nächsten Step/Reset/Finalize gültig |
SQLiteColumnBlob(stmt: int64, i: int64): int64 | BLOB-Spalte — Rohzeiger auf Daten (0 wenn NULL) |
SQLiteColumnBytes(stmt: int64, i: int64): int64 | Länge der BLOB- oder TEXT-Spalte in Bytes |
SQLiteColumnType(stmt: int64, i: int64): int64 | Typ-Code (SQLITE_INTEGER / SQLITE_FLOAT / SQLITE_TEXT / SQLITE_BLOB / SQLITE_NULL) |
SQLiteColumnIsNull(stmt: int64, i: int64): bool | Gibt true zurück wenn die Spalte NULL ist |
SQLiteColumnCount(stmt: int64): int64 | Anzahl Spalten im Ergebnis |
SQLiteColumnName(stmt: int64, i: int64): pchar | Spaltenname (0-basiert) |
Transaktionen
Transaktionsverwaltung:
| Signatur | Beschreibung |
|---|---|
SQLiteBegin(db: int64): bool | Startet eine Transaktion (BEGIN TRANSACTION) |
SQLiteCommit(db: int64): bool | Schreibt die Transaktion fest (COMMIT) |
SQLiteRollback(db: int64): bool | Macht die Transaktion rückgängig (ROLLBACK) |
SQLiteBeginImmediate(db: int64): bool | Transaktion mit sofortigem Schreib-Lock |
SQLiteBeginExclusive(db: int64): bool | Exklusive Transaktion (kein anderer Leser/Schreiber) |
SQLiteInTransaction(db: int64): bool | Gibt true zurück wenn eine Transaktion aktiv ist |
Hilfsfunktionen & Metadaten
| Signatur | Beschreibung |
|---|---|
SQLiteLastInsertId(db: int64): int64 | Rowid des letzten erfolgreichen INSERT |
SQLiteChanges(db: int64): int64 | Anzahl betroffener Zeilen des letzten INSERT/UPDATE/DELETE |
SQLiteTableExists(db: int64, table: pchar): bool | Gibt true zurück wenn die Tabelle in sqlite_master existiert |
SQLiteDropTable(db: int64, table: pchar): bool | Führt DROP TABLE IF EXISTS aus (mit Identifier-Validierung) |
SQLiteVacuum(db: int64): bool | Gibt ungenutzten Speicher in der DB-Datei frei |
SQLiteSetJournalMode(db: int64, mode: pchar): bool | Setzt den Journal-Modus: „WAL“, „DELETE„, „TRUNCATE“, „PERSIST„, „MEMORY“, „OFF„ |
SQLiteSetCacheSize(db: int64, pages: int64): bool | Setzt Cache-Größe in Seiten (PRAGMA cache_size) |
Verwendung
Tabelle erstellen und Daten einfügen
import std.db.sqlite;
import std.io;
fn SetupDB(): int64 {
var db := SQLiteOpen("/tmp/test.db");
if (db == 0) { return 0; }
SQLiteExec(db, "CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)");
return db;
}
fn InsertUser(db: int64, name: pchar, age: int64): void {
var stmt := SQLiteStmtPrepare(db, "INSERT INTO users (name, age) VALUES (?, ?)");
SQLiteBindStr(stmt, 1, name);
SQLiteBindInt(stmt, 2, age);
SQLiteStmtStep(stmt);
SQLiteStmtFinalize(stmt);
}
SELECT mit Prepared Statement
import std.db.sqlite;
import std.io;
fn PrintUsers(db: int64): void {
var stmt := SQLiteStmtPrepare(db, "SELECT id, name, age FROM users ORDER BY name");
while (SQLiteStmtStep(stmt) == SQLITE_ROW) {
PrintLn(IntToStr(SQLiteColumnInt(stmt, 0)) + ": " + SQLiteColumnText(stmt, 1) + " (" + IntToStr(SQLiteColumnInt(stmt, 2)) + ")");
}
SQLiteStmtFinalize(stmt);
}
Transaktion mit Rollback
import std.db.sqlite;
fn BulkInsert(db: int64, names: int64, count: int64): bool {
SQLiteBegin(db);
var stmt := SQLiteStmtPrepare(db, "INSERT INTO users (name) VALUES (?)");
var i: int64 := 0;
var ok: bool := true;
while (i < count) {
var name: pchar := peek64(names + i * 8) as pchar;
SQLiteBindStr(stmt, 1, name);
var rc := SQLiteStmtStep(stmt);
if (rc != SQLITE_DONE) { ok := false; break; }
SQLiteStmtReset(stmt);
i := i + 1;
}
SQLiteStmtFinalize(stmt);
if (ok) {
SQLiteCommit(db);
} else {
SQLiteRollback(db);
}
return ok;
}
In-Memory-Datenbank
import std.db.sqlite;
fn TempDB(): int64 {
var db := SQLiteOpen(":memory:");
SQLiteExec(db, "CREATE TABLE tmp (k TEXT, v TEXT)");
SQLiteSetJournalMode(db, "OFF"); // kein Journal für In-Memory nötig
return db;
}
WAL-Modus für Concurrent Reads
import std.db.sqlite;
fn OpenWAL(path: pchar): int64 {
var db := SQLiteOpen(path);
SQLiteSetJournalMode(db, "WAL");
SQLiteSetCacheSize(db, 2000); // 2000 Seiten ≈ 8 MB bei 4096 Bytes/Seite
return db;
}
Hinweise
- Parameter-Indizes bei Binding sind 1-basiert, Column-Indizes bei Accessoren sind 0-basiert.
SQLiteBindStrverwendetSQLITE_STATIC— der String-Puffer muss bis zum nächstenSQLiteStmtStep,SQLiteStmtResetoderSQLiteStmtFinalizegültig bleiben.SQLiteColumnTextgibt einen Pointer auf SQLite-internen Speicher zurück — nicht nachStep/Reset/Finalizeverwenden.- Für schreibintensive Workloads: WAL-Modus aktivieren (
SQLiteSetJournalMode(db, „WAL“)) und mehrere INSERT in Transaktionen bündeln. SQLiteDropTablevalidiert den Tabellennamen auf erlaubte Zeichen (A-Z, a-z, 0-9, _, .) — schützt vor SQL-Injection.
Verwandte Units
std.db.postgres— PostgreSQL (natives Wire-Protokoll)std.db.mysql— MySQL/MariaDBstd.db.redis— Redis Key-Value-Store
Letzte Aktualisierung: 2026-06-05
