const std = @import("std"); const c = @cImport(@cInclude("sqlite3ext.h")); pub export var sqlite3_api: [*c]const c.sqlite3_api_routines = null; const maxPathSize = 256; const blocksize = 512; const blobsize = 1474560; const BlockFile = struct { base: c.sqlite3_file }; fn xOpen(vfs: [*c]c.sqlite3_vfs, zName: [*c]const u8, f: [*c]c.sqlite3_file, flags: c_int, pOutFlags: [*c]c_int) callconv(.C) c_int { std.debug.print("xOpen: zName={s} flags={d}\n", .{ zName, flags }); return c.SQLITE_ERROR; } fn xDelete(vfs: [*c]c.sqlite3_vfs, zName: [*c]const u8, syncDir: c_int) callconv(.C) c_int { return c.SQLITE_ERROR; } fn xAccess(vfs: [*c]c.sqlite3_vfs, zName: [*c]const u8, flags: c_int, pResOut: [*c]c_int) callconv(.C) c_int { return c.SQLITE_ERROR; } fn xFullPathname(vfs: [*c]c.sqlite3_vfs, zName: [*c]const u8, nOut: c_int, zOut: [*c]u8) callconv(.C) c_int { std.debug.print("xFullPathname: zName={s} nOut={d}\n", .{ zName, nOut }); const out = zOut[0..@intCast(usize, nOut)]; const name = std.mem.spanZ(zName); if (name.len + 1 > maxPathSize) { return c.SQLITE_CANTOPEN; } out[0] = '/'; std.mem.copy(u8, out[1..out.len], name); return c.SQLITE_OK; } fn xDlOpen(vfs: [*c]c.sqlite3_vfs, zFilename: [*c]const u8) callconv(.C) ?*c_void { return null; } fn xDlError(vfs: [*c]c.sqlite3_vfs, nByte: c_int, zErrMsg: [*c]u8) callconv(.C) void {} fn xDlSym(vfs: [*c]c.sqlite3_vfs, pHandle: ?*c_void, zSymbol: [*c]const u8) callconv(.C) ?fn () callconv(.C) void { return xDlSym_; } fn xDlSym_() callconv(.C) void {} fn xDlClose(vfs: [*c]c.sqlite3_vfs, pHandle: ?*c_void) callconv(.C) void {} fn xRandomness(vfs: [*c]c.sqlite3_vfs, nByte: c_int, zOut: [*c]u8) callconv(.C) c_int { return c.SQLITE_ERROR; } fn xSleep(vfs: [*c]c.sqlite3_vfs, microseconds: c_int) callconv(.C) c_int { return c.SQLITE_ERROR; } fn xCurrentTime(vfs: [*c]c.sqlite3_vfs, prNow: [*c]f64) callconv(.C) c_int { return c.SQLITE_ERROR; } fn xGetLastError(vfs: [*c]c.sqlite3_vfs, nBuf: c_int, zBuf: [*c]u8) callconv(.C) c_int { return c.SQLITE_ERROR; } var blockvfs = c.sqlite3_vfs{ .iVersion = 1, .szOsFile = @sizeOf(BlockFile), .mxPathname = maxPathSize, .pNext = null, .zName = "blockvfs", .pAppData = null, .xOpen = xOpen, .xDelete = xDelete, .xAccess = xAccess, .xFullPathname = xFullPathname, .xDlOpen = xDlOpen, .xDlError = xDlError, .xDlSym = xDlSym, .xDlClose = xDlClose, .xRandomness = xRandomness, .xSleep = xSleep, .xCurrentTime = xCurrentTime, .xGetLastError = xGetLastError, .xCurrentTimeInt64 = null, .xGetSystemCall = null, .xSetSystemCall = null, .xNextSystemCall = null, }; pub export fn blockvfs_register() c_int { std.debug.print("hello {s}!\n", .{blockvfs.zName}); return sqlite3_api.*.vfs_register.?(&blockvfs, 0); } pub export fn sqlite3_blockvfs_init(db: ?*c.sqlite3, pzErrMsg: [*c][*c]u8, pApi: [*c]const c.sqlite3_api_routines) c_int { sqlite3_api = pApi; const ret = blockvfs_register(); return switch (ret) { c.SQLITE_OK => c.SQLITE_OK_LOAD_PERMANENTLY, else => ret, }; }