1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
|
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,
};
}
|