Skip to content

Commit 151e50f

Browse files
committed
fix: create parent dirs when opening palace.db
Default ~/.memxt/palace.db failed on fresh CI/runner home with no .memxt directory. mkdir parents before sqlite3_open.
1 parent 26eae66 commit 151e50f

2 files changed

Lines changed: 32 additions & 1 deletion

File tree

build.zig.zon

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
.{
22
.name = .memxt,
3-
.version = "0.3.1",
3+
.version = "0.3.2",
44
.fingerprint = 0x5bf95d78bca15787,
55
.minimum_zig_version = "0.16.0",
66
.paths = .{

src/db.zig

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ pub const c = @cImport({
1313
@cInclude("sqlite-vec.h");
1414
});
1515

16+
const posix = @cImport({
17+
@cInclude("sys/stat.h");
18+
@cInclude("sys/types.h");
19+
});
20+
1621
/// Bump when the on-disk schema changes; add a migration branch in
1722
/// `migrateSchema` for each step. Persisted via SQLite's `PRAGMA user_version`.
1823
/// v2: FTS5 full-text index for hybrid keyword + vector search.
@@ -33,6 +38,10 @@ pub const Database = struct {
3338
handle: *Sqlite3,
3439

3540
pub fn open(path: [*:0]const u8) !Database {
41+
// Ensure parent directory exists (e.g. ~/.memxt/ for the default palace).
42+
// sqlite3_open does not create intermediate directories.
43+
ensureParentDirs(std.mem.span(path));
44+
3645
var handle: ?*Sqlite3 = null;
3746
if (c.sqlite3_open(path, &handle) != SQLITE_OK) {
3847
if (handle) |h| _ = c.sqlite3_close(h);
@@ -408,6 +417,28 @@ pub const Database = struct {
408417
}
409418
};
410419

420+
/// Create every intermediate directory for an absolute or relative DB path.
421+
/// Best-effort: ignores EEXIST and other races. sqlite3_open will not mkdir.
422+
fn ensureParentDirs(path: []const u8) void {
423+
const dir = std.fs.path.dirname(path) orelse return;
424+
if (dir.len == 0) return;
425+
var i: usize = 0;
426+
while (i < dir.len) : (i += 1) {
427+
if (dir[i] != '/') continue;
428+
if (i == 0) continue; // skip root "/"
429+
var buf: [std.fs.max_path_bytes]u8 = undefined;
430+
if (i >= buf.len) return;
431+
@memcpy(buf[0..i], dir[0..i]);
432+
buf[i] = 0;
433+
_ = posix.mkdir(&buf, 0o755);
434+
}
435+
var final_buf: [std.fs.max_path_bytes]u8 = undefined;
436+
if (dir.len >= final_buf.len) return;
437+
@memcpy(final_buf[0..dir.len], dir);
438+
final_buf[dir.len] = 0;
439+
_ = posix.mkdir(&final_buf, 0o755);
440+
}
441+
411442
// ── Statement helpers ──
412443

413444
pub fn finalize(stmt: ?*Stmt) void {

0 commit comments

Comments
 (0)