New features: - Blob I/O: Incremental read/write for large BLOBs - Blob.open(), close(), deinit() - Blob.read(), write() with offset support - Blob.bytes(), reopen(), readAll() - Hooks: Monitor database changes - setCommitHook() - called on transaction commit - setRollbackHook() - called on transaction rollback - setUpdateHook() - called on INSERT/UPDATE/DELETE - clearHooks() - remove all hooks - UpdateOperation enum (insert, update, delete) - Aggregate Functions: Custom multi-row aggregates - createAggregateFunction(name, num_args, step_fn, final_fn) - AggregateContext with getAggregateContext() for state management - Support for setNull/Int/Float/Text/Blob/Error results Documentation: - Updated docs/API.md to v0.4 with new features and examples - Updated docs/CGO_PARITY_ANALYSIS.md - Fase 3A marked complete - Updated CLAUDE.md to v0.4 with all new implementations Tests: 28 total (8 new tests for Fase 3A features) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
698 lines
16 KiB
Markdown
698 lines
16 KiB
Markdown
# zsqlite - API Reference
|
|
|
|
> **Version**: 0.4
|
|
> **Ultima actualizacion**: 2025-12-08
|
|
|
|
## Quick Reference
|
|
|
|
```zig
|
|
const sqlite = @import("zsqlite");
|
|
|
|
// Abrir base de datos
|
|
var db = try sqlite.openMemory(); // In-memory
|
|
var db = try sqlite.open("file.db"); // Archivo
|
|
defer db.close();
|
|
|
|
// SQL directo
|
|
try db.exec("CREATE TABLE ...");
|
|
|
|
// Prepared statement
|
|
var stmt = try db.prepare("SELECT * FROM users WHERE id = ?");
|
|
defer stmt.finalize();
|
|
try stmt.bindInt(1, 42);
|
|
while (try stmt.step()) {
|
|
const name = stmt.columnText(1);
|
|
}
|
|
|
|
// Named parameters
|
|
var stmt = try db.prepare("INSERT INTO users VALUES (:name, :age)");
|
|
try stmt.bindTextNamed(":name", "Alice");
|
|
try stmt.bindIntNamed(":age", 30);
|
|
|
|
// Transacciones
|
|
try db.begin();
|
|
// ... operaciones ...
|
|
try db.commit(); // o db.rollback()
|
|
|
|
// Savepoints
|
|
try db.savepoint(allocator, "sp1");
|
|
try db.rollbackTo(allocator, "sp1");
|
|
try db.release(allocator, "sp1");
|
|
|
|
// Backup
|
|
try sqlite.backupToFile(&db, "backup.db");
|
|
var restored = try sqlite.loadFromFile("backup.db");
|
|
|
|
// User-defined functions
|
|
try db.createScalarFunction("double", 1, myDoubleFunc);
|
|
try db.createAggregateFunction("sum_squares", 1, stepFn, finalFn);
|
|
|
|
// Custom collations
|
|
try db.createCollation("NOCASE2", myCaseInsensitiveCompare);
|
|
|
|
// Blob I/O
|
|
var blob = try sqlite.Blob.open(&db, "main", "table", "column", rowid, true);
|
|
defer blob.deinit();
|
|
try blob.write(data, 0);
|
|
try blob.read(&buffer, 0);
|
|
|
|
// Hooks
|
|
try db.setCommitHook(myCommitHook);
|
|
try db.setUpdateHook(myUpdateHook);
|
|
```
|
|
|
|
---
|
|
|
|
## Funciones de Modulo
|
|
|
|
### open
|
|
|
|
```zig
|
|
pub fn open(path: [:0]const u8) Error!Database
|
|
```
|
|
|
|
Abre una base de datos SQLite.
|
|
|
|
**Parametros:**
|
|
- `path`: Ruta al archivo. Usar `":memory:"` para base de datos en memoria.
|
|
|
|
**Retorna:** `Database` o error.
|
|
|
|
---
|
|
|
|
### openMemory
|
|
|
|
```zig
|
|
pub fn openMemory() Error!Database
|
|
```
|
|
|
|
Abre una base de datos en memoria.
|
|
|
|
---
|
|
|
|
### version / versionNumber
|
|
|
|
```zig
|
|
pub fn version() []const u8
|
|
pub fn versionNumber() i32
|
|
```
|
|
|
|
Retorna la version de SQLite como string ("3.47.2") o numero (3047002).
|
|
|
|
---
|
|
|
|
### backupDatabase
|
|
|
|
```zig
|
|
pub fn backupDatabase(dest_db: *Database, source_db: *Database) Error!void
|
|
```
|
|
|
|
Copia una base de datos completa a otra.
|
|
|
|
---
|
|
|
|
### backupToFile
|
|
|
|
```zig
|
|
pub fn backupToFile(source_db: *Database, path: [:0]const u8) Error!void
|
|
```
|
|
|
|
Guarda una base de datos a un archivo.
|
|
|
|
---
|
|
|
|
### loadFromFile
|
|
|
|
```zig
|
|
pub fn loadFromFile(path: [:0]const u8) Error!Database
|
|
```
|
|
|
|
Carga una base de datos desde archivo a memoria.
|
|
|
|
---
|
|
|
|
## Database
|
|
|
|
### Apertura y Cierre
|
|
|
|
| Funcion | Descripcion |
|
|
|---------|-------------|
|
|
| `open(path)` | Abre conexion (read-write, create) |
|
|
| `openWithFlags(path, flags)` | Abre con flags especificos |
|
|
| `close()` | Cierra la conexion |
|
|
|
|
### Ejecucion SQL
|
|
|
|
| Funcion | Descripcion |
|
|
|---------|-------------|
|
|
| `exec(sql)` | Ejecuta SQL sin resultados |
|
|
| `execAlloc(alloc, sql)` | exec con string runtime |
|
|
| `prepare(sql)` | Crea prepared statement |
|
|
| `prepareAlloc(alloc, sql)` | prepare con string runtime |
|
|
|
|
### Transacciones
|
|
|
|
| Funcion | Descripcion |
|
|
|---------|-------------|
|
|
| `begin()` | Inicia transaccion (DEFERRED) |
|
|
| `beginImmediate()` | Inicia con lock inmediato |
|
|
| `beginExclusive()` | Inicia con lock exclusivo |
|
|
| `commit()` | Confirma transaccion |
|
|
| `rollback()` | Revierte transaccion |
|
|
|
|
### Savepoints
|
|
|
|
```zig
|
|
pub fn savepoint(self: *Database, allocator: Allocator, name: []const u8) !void
|
|
pub fn release(self: *Database, allocator: Allocator, name: []const u8) !void
|
|
pub fn rollbackTo(self: *Database, allocator: Allocator, name: []const u8) !void
|
|
```
|
|
|
|
Savepoints permiten transacciones anidadas.
|
|
|
|
**Ejemplo:**
|
|
```zig
|
|
try db.begin();
|
|
try db.savepoint(alloc, "sp1");
|
|
try db.exec("INSERT ...");
|
|
try db.rollbackTo(alloc, "sp1"); // Revierte INSERT
|
|
try db.release(alloc, "sp1");
|
|
try db.commit();
|
|
```
|
|
|
|
### Configuracion
|
|
|
|
| Funcion | Descripcion |
|
|
|---------|-------------|
|
|
| `setForeignKeys(enabled)` | Habilita/deshabilita FKs |
|
|
| `setBusyTimeout(ms)` | Timeout en ms para locks |
|
|
| `setJournalMode(alloc, mode)` | "WAL", "DELETE", etc |
|
|
| `setSynchronous(alloc, mode)` | "OFF", "NORMAL", "FULL" |
|
|
| `enableWalMode(alloc)` | WAL + NORMAL sync |
|
|
|
|
### ATTACH/DETACH
|
|
|
|
```zig
|
|
pub fn attach(self: *Database, alloc: Allocator, path: []const u8, schema: []const u8) !void
|
|
pub fn attachMemory(self: *Database, alloc: Allocator, schema: []const u8) !void
|
|
pub fn detach(self: *Database, alloc: Allocator, schema: []const u8) !void
|
|
pub fn listDatabases(self: *Database, alloc: Allocator) ![][]const u8
|
|
pub fn freeDatabaseList(alloc: Allocator, list: [][]const u8) void
|
|
```
|
|
|
|
**Ejemplo:**
|
|
```zig
|
|
try db.attachMemory(alloc, "cache");
|
|
try db.exec("CREATE TABLE cache.items (...)");
|
|
// SELECT * FROM cache.items
|
|
try db.detach(alloc, "cache");
|
|
```
|
|
|
|
### User-Defined Functions
|
|
|
|
```zig
|
|
pub fn createScalarFunction(
|
|
self: *Database,
|
|
name: [:0]const u8,
|
|
num_args: i32,
|
|
func: ScalarFn,
|
|
) !void
|
|
|
|
pub fn removeFunction(self: *Database, name: [:0]const u8, num_args: i32) Error!void
|
|
```
|
|
|
|
**Ejemplo:**
|
|
```zig
|
|
fn myDouble(ctx: FunctionContext, args: []const FunctionValue) void {
|
|
if (args[0].isNull()) {
|
|
ctx.setNull();
|
|
return;
|
|
}
|
|
ctx.setInt(args[0].asInt() * 2);
|
|
}
|
|
|
|
try db.createScalarFunction("double", 1, myDouble);
|
|
// SELECT double(value) FROM table
|
|
```
|
|
|
|
### Custom Collations
|
|
|
|
```zig
|
|
pub fn createCollation(self: *Database, name: [:0]const u8, func: CollationFn) !void
|
|
pub fn removeCollation(self: *Database, name: [:0]const u8) Error!void
|
|
```
|
|
|
|
**Ejemplo:**
|
|
```zig
|
|
fn reverseOrder(a: []const u8, b: []const u8) i32 {
|
|
return -std.mem.order(u8, a, b);
|
|
}
|
|
|
|
try db.createCollation("REVERSE", reverseOrder);
|
|
// SELECT * FROM table ORDER BY name COLLATE REVERSE
|
|
```
|
|
|
|
### Utilidades
|
|
|
|
| Funcion | Descripcion |
|
|
|---------|-------------|
|
|
| `lastInsertRowId()` | Ultimo rowid insertado |
|
|
| `changes()` | Filas modificadas (ultimo stmt) |
|
|
| `totalChanges()` | Total filas desde conexion |
|
|
| `errorMessage()` | Mensaje de error reciente |
|
|
| `errorCode()` | Codigo de error |
|
|
| `extendedErrorCode()` | Codigo extendido |
|
|
| `interrupt()` | Interrumpe operacion |
|
|
| `isReadOnly(db_name)` | Si DB es readonly |
|
|
| `filename(db_name)` | Ruta del archivo |
|
|
|
|
---
|
|
|
|
## Statement
|
|
|
|
### Ciclo de Vida
|
|
|
|
| Funcion | Descripcion |
|
|
|---------|-------------|
|
|
| `finalize()` | Libera el statement |
|
|
| `reset()` | Resetea para re-ejecucion |
|
|
| `clearBindings()` | Limpia parametros |
|
|
| `step()` | Ejecuta un paso (true=hay fila) |
|
|
|
|
### Metadata
|
|
|
|
| Funcion | Descripcion |
|
|
|---------|-------------|
|
|
| `sql()` | Texto SQL del statement |
|
|
| `isReadOnly()` | Si es SELECT |
|
|
| `parameterCount()` | Numero de parametros |
|
|
| `parameterIndex(name)` | Indice de parametro named |
|
|
| `parameterName(index)` | Nombre de parametro |
|
|
|
|
### Bind Parameters (1-indexed)
|
|
|
|
| Funcion | Descripcion |
|
|
|---------|-------------|
|
|
| `bindNull(idx)` | NULL |
|
|
| `bindInt(idx, val)` | i64 |
|
|
| `bindFloat(idx, val)` | f64 |
|
|
| `bindText(idx, val)` | []const u8 |
|
|
| `bindBlob(idx, val)` | []const u8 |
|
|
| `bindBool(idx, val)` | bool (como 0/1) |
|
|
| `bindZeroblob(idx, size)` | Blob de ceros |
|
|
|
|
### Named Parameters
|
|
|
|
| Funcion | Descripcion |
|
|
|---------|-------------|
|
|
| `bindNullNamed(name)` | `:name`, `@name`, `$name` |
|
|
| `bindIntNamed(name, val)` | |
|
|
| `bindFloatNamed(name, val)` | |
|
|
| `bindTextNamed(name, val)` | |
|
|
| `bindBlobNamed(name, val)` | |
|
|
| `bindBoolNamed(name, val)` | |
|
|
|
|
### Column Access (0-indexed)
|
|
|
|
| Funcion | Descripcion |
|
|
|---------|-------------|
|
|
| `columnCount()` | Numero de columnas |
|
|
| `columnName(idx)` | Nombre |
|
|
| `columnType(idx)` | ColumnType enum |
|
|
| `columnInt(idx)` | i64 |
|
|
| `columnFloat(idx)` | f64 |
|
|
| `columnText(idx)` | ?[]const u8 |
|
|
| `columnBlob(idx)` | ?[]const u8 |
|
|
| `columnBool(idx)` | bool |
|
|
| `columnIsNull(idx)` | bool |
|
|
| `columnBytes(idx)` | Tamano en bytes |
|
|
| `columnDeclType(idx)` | Tipo declarado |
|
|
|
|
---
|
|
|
|
## Backup
|
|
|
|
```zig
|
|
pub const Backup = struct {
|
|
pub fn init(dest: *Database, dest_name: [:0]const u8,
|
|
source: *Database, source_name: [:0]const u8) Error!Backup
|
|
pub fn initMain(dest: *Database, source: *Database) Error!Backup
|
|
pub fn step(self: *Backup, n_pages: i32) Error!bool
|
|
pub fn stepAll(self: *Backup) Error!void
|
|
pub fn remaining(self: *Backup) i32
|
|
pub fn pageCount(self: *Backup) i32
|
|
pub fn progress(self: *Backup) u8 // 0-100
|
|
pub fn finish(self: *Backup) Error!void
|
|
pub fn deinit(self: *Backup) void
|
|
};
|
|
```
|
|
|
|
**Ejemplo con progreso:**
|
|
```zig
|
|
var backup = try Backup.initMain(&dest_db, &source_db);
|
|
defer backup.deinit();
|
|
|
|
while (try backup.step(100)) {
|
|
std.debug.print("Progress: {}%\n", .{backup.progress()});
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## User-Defined Functions
|
|
|
|
### FunctionContext
|
|
|
|
```zig
|
|
pub const FunctionContext = struct {
|
|
pub fn setNull(self: Self) void
|
|
pub fn setInt(self: Self, value: i64) void
|
|
pub fn setFloat(self: Self, value: f64) void
|
|
pub fn setText(self: Self, value: []const u8) void
|
|
pub fn setBlob(self: Self, value: []const u8) void
|
|
pub fn setError(self: Self, msg: []const u8) void
|
|
};
|
|
```
|
|
|
|
### FunctionValue
|
|
|
|
```zig
|
|
pub const FunctionValue = struct {
|
|
pub fn getType(self: Self) ColumnType
|
|
pub fn isNull(self: Self) bool
|
|
pub fn asInt(self: Self) i64
|
|
pub fn asFloat(self: Self) f64
|
|
pub fn asText(self: Self) ?[]const u8
|
|
pub fn asBlob(self: Self) ?[]const u8
|
|
};
|
|
```
|
|
|
|
### ScalarFn Type
|
|
|
|
```zig
|
|
pub const ScalarFn = *const fn (ctx: FunctionContext, args: []const FunctionValue) void;
|
|
```
|
|
|
|
---
|
|
|
|
## Types
|
|
|
|
### OpenFlags
|
|
|
|
```zig
|
|
pub const OpenFlags = struct {
|
|
read_only: bool = false,
|
|
read_write: bool = true,
|
|
create: bool = true,
|
|
uri: bool = false,
|
|
memory: bool = false,
|
|
no_mutex: bool = false,
|
|
full_mutex: bool = false,
|
|
};
|
|
```
|
|
|
|
### ColumnType
|
|
|
|
```zig
|
|
pub const ColumnType = enum {
|
|
integer,
|
|
float,
|
|
text,
|
|
blob,
|
|
null_value,
|
|
};
|
|
```
|
|
|
|
### CollationFn
|
|
|
|
```zig
|
|
pub const CollationFn = *const fn (a: []const u8, b: []const u8) i32;
|
|
```
|
|
|
|
Retorna: negativo si a < b, cero si a == b, positivo si a > b.
|
|
|
|
### Error
|
|
|
|
Mapeo completo de codigos SQLite:
|
|
|
|
| Error | Descripcion |
|
|
|-------|-------------|
|
|
| `SqliteError` | Error generico |
|
|
| `Busy` | Database bloqueada |
|
|
| `Locked` | Tabla bloqueada |
|
|
| `Constraint` | Violacion de constraint |
|
|
| `OutOfMemory` | Sin memoria |
|
|
| `IoError` | Error de I/O |
|
|
| `Corrupt` | DB corrupta |
|
|
| `CantOpen` | No se puede abrir |
|
|
| `ReadOnly` | DB es readonly |
|
|
| `Range` | Parametro fuera de rango |
|
|
| ... | (25+ errores mapeados) |
|
|
|
|
---
|
|
|
|
## Ejemplos Completos
|
|
|
|
### CRUD con Named Parameters
|
|
|
|
```zig
|
|
var db = try sqlite.openMemory();
|
|
defer db.close();
|
|
|
|
try db.exec("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)");
|
|
|
|
// Insert con named params
|
|
var insert = try db.prepare("INSERT INTO users (name, age) VALUES (:name, :age)");
|
|
defer insert.finalize();
|
|
|
|
try insert.bindTextNamed(":name", "Alice");
|
|
try insert.bindIntNamed(":age", 30);
|
|
_ = try insert.step();
|
|
|
|
// Query
|
|
var query = try db.prepare("SELECT * FROM users WHERE age > :min_age");
|
|
defer query.finalize();
|
|
|
|
try query.bindIntNamed(":min_age", 25);
|
|
while (try query.step()) {
|
|
const name = query.columnText(1) orelse "(null)";
|
|
std.debug.print("User: {s}\n", .{name});
|
|
}
|
|
```
|
|
|
|
### Backup con Progreso
|
|
|
|
```zig
|
|
var source = try sqlite.open("production.db");
|
|
defer source.close();
|
|
|
|
var dest = try sqlite.open("backup.db");
|
|
defer dest.close();
|
|
|
|
var backup = try sqlite.Backup.initMain(&dest, &source);
|
|
defer backup.deinit();
|
|
|
|
while (try backup.step(100)) {
|
|
const pct = backup.progress();
|
|
std.debug.print("\rBackup: {d}%", .{pct});
|
|
}
|
|
std.debug.print("\nBackup complete!\n", .{});
|
|
```
|
|
|
|
### UDF: String Length
|
|
|
|
```zig
|
|
fn strLen(ctx: sqlite.FunctionContext, args: []const sqlite.FunctionValue) void {
|
|
if (args.len != 1 or args[0].isNull()) {
|
|
ctx.setNull();
|
|
return;
|
|
}
|
|
if (args[0].asText()) |text| {
|
|
ctx.setInt(@intCast(text.len));
|
|
} else {
|
|
ctx.setNull();
|
|
}
|
|
}
|
|
|
|
try db.createScalarFunction("strlen", 1, strLen);
|
|
// SELECT strlen(name) FROM users
|
|
```
|
|
|
|
### Collation: Case-Insensitive
|
|
|
|
```zig
|
|
fn caseInsensitive(a: []const u8, b: []const u8) i32 {
|
|
var i: usize = 0;
|
|
while (i < a.len and i < b.len) : (i += 1) {
|
|
const ca = std.ascii.toLower(a[i]);
|
|
const cb = std.ascii.toLower(b[i]);
|
|
if (ca < cb) return -1;
|
|
if (ca > cb) return 1;
|
|
}
|
|
if (a.len < b.len) return -1;
|
|
if (a.len > b.len) return 1;
|
|
return 0;
|
|
}
|
|
|
|
try db.createCollation("ICASE", caseInsensitive);
|
|
// SELECT * FROM users ORDER BY name COLLATE ICASE
|
|
```
|
|
|
|
### Aggregate Function: Sum of Squares
|
|
|
|
```zig
|
|
const SumState = struct {
|
|
total: i64 = 0,
|
|
};
|
|
|
|
fn sumSquaresStep(ctx: sqlite.AggregateContext, args: []const sqlite.FunctionValue) void {
|
|
const state = ctx.getAggregateContext(SumState) orelse return;
|
|
if (args.len > 0 and !args[0].isNull()) {
|
|
const val = args[0].asInt();
|
|
state.total += val * val;
|
|
}
|
|
}
|
|
|
|
fn sumSquaresFinal(ctx: sqlite.AggregateContext) void {
|
|
const state = ctx.getAggregateContext(SumState) orelse {
|
|
ctx.setNull();
|
|
return;
|
|
};
|
|
ctx.setInt(state.total);
|
|
}
|
|
|
|
try db.createAggregateFunction("sum_squares", 1, sumSquaresStep, sumSquaresFinal);
|
|
// SELECT sum_squares(value) FROM numbers => 1+4+9+16+25 = 55
|
|
```
|
|
|
|
### Blob I/O: Incremental Read/Write
|
|
|
|
```zig
|
|
// Insert placeholder blob
|
|
try db.exec("INSERT INTO files (data) VALUES (zeroblob(1024))");
|
|
const rowid = db.lastInsertRowId();
|
|
|
|
// Open for writing
|
|
var blob = try sqlite.Blob.open(&db, "main", "files", "data", rowid, true);
|
|
defer blob.deinit();
|
|
|
|
// Write data
|
|
try blob.write("Hello, World!", 0);
|
|
|
|
// Read data
|
|
var buffer: [100]u8 = undefined;
|
|
try blob.read(&buffer, 0);
|
|
```
|
|
|
|
### Hooks: Monitor Database Changes
|
|
|
|
```zig
|
|
fn onCommit() bool {
|
|
std.debug.print("Transaction committed!\n", .{});
|
|
return true; // Allow commit
|
|
}
|
|
|
|
fn onUpdate(op: sqlite.UpdateOperation, db_name: []const u8, table: []const u8, rowid: i64) void {
|
|
std.debug.print("{s} on {s}.{s} row {d}\n", .{
|
|
@tagName(op), db_name, table, rowid
|
|
});
|
|
}
|
|
|
|
try db.setCommitHook(onCommit);
|
|
try db.setUpdateHook(onUpdate);
|
|
// ... operations will trigger hooks ...
|
|
db.clearHooks(); // Remove all hooks
|
|
```
|
|
|
|
---
|
|
|
|
## Blob
|
|
|
|
```zig
|
|
pub const Blob = struct {
|
|
pub fn open(db: *Database, schema: [:0]const u8, table: [:0]const u8,
|
|
column: [:0]const u8, rowid: i64, writable: bool) Error!Blob
|
|
pub fn openAlloc(db: *Database, allocator: Allocator, ...) !Blob
|
|
pub fn close(self: *Blob) Error!void
|
|
pub fn deinit(self: *Blob) void
|
|
pub fn bytes(self: *Blob) i32
|
|
pub fn read(self: *Blob, buffer: []u8, offset: i32) Error!void
|
|
pub fn write(self: *Blob, data: []const u8, offset: i32) Error!void
|
|
pub fn reopen(self: *Blob, rowid: i64) Error!void
|
|
pub fn readAll(self: *Blob, allocator: Allocator) ![]u8
|
|
};
|
|
```
|
|
|
|
---
|
|
|
|
## Hooks
|
|
|
|
### Types
|
|
|
|
```zig
|
|
pub const ZigCommitHookFn = *const fn () bool;
|
|
pub const ZigRollbackHookFn = *const fn () void;
|
|
pub const ZigUpdateHookFn = *const fn (
|
|
operation: UpdateOperation,
|
|
db_name: []const u8,
|
|
table_name: []const u8,
|
|
rowid: i64
|
|
) void;
|
|
|
|
pub const UpdateOperation = enum(i32) {
|
|
insert,
|
|
update,
|
|
delete,
|
|
};
|
|
```
|
|
|
|
### Database Methods
|
|
|
|
| Method | Description |
|
|
|--------|-------------|
|
|
| `setCommitHook(fn)` | Called when transaction commits |
|
|
| `setRollbackHook(fn)` | Called when transaction rolls back |
|
|
| `setUpdateHook(fn)` | Called on INSERT/UPDATE/DELETE |
|
|
| `clearHooks()` | Remove all hooks |
|
|
|
|
---
|
|
|
|
## Aggregate Functions
|
|
|
|
### Types
|
|
|
|
```zig
|
|
pub const AggregateStepFn = *const fn (ctx: AggregateContext, args: []const FunctionValue) void;
|
|
pub const AggregateFinalFn = *const fn (ctx: AggregateContext) void;
|
|
```
|
|
|
|
### AggregateContext
|
|
|
|
```zig
|
|
pub const AggregateContext = struct {
|
|
pub fn getAggregateContext(self: Self, comptime T: type) ?*T
|
|
pub fn setNull(self: Self) void
|
|
pub fn setInt(self: Self, value: i64) void
|
|
pub fn setFloat(self: Self, value: f64) void
|
|
pub fn setText(self: Self, value: []const u8) void
|
|
pub fn setBlob(self: Self, value: []const u8) void
|
|
pub fn setError(self: Self, msg: []const u8) void
|
|
};
|
|
```
|
|
|
|
### Database Method
|
|
|
|
```zig
|
|
pub fn createAggregateFunction(
|
|
self: *Database,
|
|
name: [:0]const u8,
|
|
num_args: i32,
|
|
step_fn: AggregateStepFn,
|
|
final_fn: AggregateFinalFn,
|
|
) !void
|
|
```
|
|
|
|
---
|
|
|
|
**© zsqlite v0.4 - API Reference**
|
|
*2025-12-08*
|