search for standard sites
pub-search.waow.tech
search
zig
blog
atproto
2.9 kB
93 lines
1const std = @import("std");
2const Io = std.Io;
3const logfire = @import("logfire");
4
5const schema = @import("db/schema.zig");
6const result = @import("db/result.zig");
7
8// re-exports
9pub const Client = @import("db/Client.zig");
10pub const LocalDb = @import("db/LocalDb.zig");
11pub const Row = result.Row;
12pub const Result = result.Result;
13pub const BatchResult = result.BatchResult;
14
15// global state
16const allocator = std.heap.smp_allocator;
17var client: ?Client = null;
18var local_db: ?LocalDb = null;
19
20/// Initialize Turso client only (fast, call synchronously at startup).
21/// Schema migrations run separately via initSchema() in the background thread
22/// so a slow/unreachable turso doesn't block the accept loop.
23pub fn initTurso(io: Io) !void {
24 client = try Client.init(allocator, io);
25}
26
27/// Run schema migrations via zug. Call from background thread.
28///
29/// On an existing turso DB, `schema.bootstrapIfNeeded` seeds the
30/// `zug_migrations` table on first run so no migrations actually execute.
31/// On a fresh DB, the full migration list runs from scratch.
32pub fn initSchema() void {
33 if (client) |*c| {
34 schema.init(allocator, c) catch |err| {
35 logfire.err("schema init failed: {s}", .{@errorName(err)});
36 };
37 }
38}
39
40/// Initialize local SQLite replica (slow, call in background thread)
41pub fn initLocalDb(io: Io) void {
42 initLocal(io) catch |err| {
43 std.debug.print("local db init failed (will use turso only): {}\n", .{err});
44 };
45}
46
47fn initLocal(io: Io) !void {
48 // check if local db is disabled
49 if (std.c.getenv("LOCAL_DB_ENABLED")) |p| {
50 const val = std.mem.span(p);
51 if (std.mem.eql(u8, val, "false") or std.mem.eql(u8, val, "0")) {
52 std.debug.print("local db disabled via LOCAL_DB_ENABLED\n", .{});
53 return;
54 }
55 }
56
57 local_db = LocalDb.init(allocator, io);
58 try local_db.?.open();
59}
60
61pub fn getClient() ?*Client {
62 if (client) |*c| return c;
63 return null;
64}
65
66pub fn startKeepalive() void {
67 if (client) |*c| c.startKeepalive();
68}
69
70/// Get local db if ready (synced and available)
71pub fn getLocalDb() ?*LocalDb {
72 if (local_db) |*l| {
73 if (l.isReady()) return l;
74 }
75 return null;
76}
77
78/// Get local db even if not ready (for sync operations)
79pub fn getLocalDbRaw() ?*LocalDb {
80 if (local_db) |*l| return l;
81 return null;
82}
83
84/// Mark the local replica ready to serve. In-place Turso→replica sync was
85/// deleted (2026-06-26): the serving box's replica is refreshed only by
86/// verified snapshot adoption at boot, never by background data movement
87/// (the 2026-06-10 invariant). Kept as a named call so main.zig's startup
88/// sequence reads unchanged.
89pub fn startSync(io: Io) void {
90 _ = io;
91 if (getLocalDbRaw()) |l| l.setReady(true);
92 std.debug.print("sync: in-place sync removed — serving adopted snapshot as-is\n", .{});
93}