From 17cf22ddfdb19d4491620c8a428f359bce8007d1 Mon Sep 17 00:00:00 2001 From: Spencer Brower Date: Sun, 3 May 2026 13:03:14 -0400 Subject: [PATCH] wip: Restore db from file. --- fixtures/encrypted-single-file.db.age | Bin 0 -> 12500 bytes src/Db.zig | 100 +++++++++++++++++++++++--- zig-vendor/zig-sqlite/sqlite.zig | 2 +- 3 files changed, 90 insertions(+), 12 deletions(-) create mode 100644 fixtures/encrypted-single-file.db.age diff --git a/fixtures/encrypted-single-file.db.age b/fixtures/encrypted-single-file.db.age new file mode 100644 index 0000000000000000000000000000000000000000..613d717372618c95512b9dbf9890251a002831a1 GIT binary patch literal 12500 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 literal 0 HcmV?d00001 diff --git a/src/Db.zig b/src/Db.zig index bda2903..b9d1a6d 100644 --- a/src/Db.zig +++ b/src/Db.zig @@ -40,6 +40,7 @@ pub fn open( defer gpa.free(tmp_db_path); // TODO: Use std.MultiArrayList? Had json issues + // FIXME: Create a .deinit function to free this memory var private_keys: std.ArrayList([]const u8) = try .initCapacity( gpa, opts.config.keys.len, @@ -75,7 +76,10 @@ const OpenOptions = struct { fn new(config: Config) !@This() { var db = try sqlite.Db.init(.{ .mode = .Memory, - .open_flags = .{ .write = true, .create = true }, + .open_flags = .{ + .write = true, + .create = true, + }, .threading_mode = .MultiThread, }); @@ -114,13 +118,21 @@ fn restore( .{}, .{path}, ); + std.debug.print("path: {s}\n", .{path}); defer self.sql_db.exec("DETACH DATABASE source", .{}, .{}) catch unreachable; - try self.sql_db.exec( + var diags: sqlite.Diagnostics = .{}; + self.sql_db.exec( "INSERT INTO main.envr_env_files SELECT * FROM source.envr_env_files", + .{ .diags = &diags }, .{}, - .{}, - ); + ) catch |err| { + std.log.err( + "unable to prepare statement, got error {}. diagnostics: {f}", + .{ err, diags }, + ); + return err; + }; } // TODO: Finish @@ -171,21 +183,24 @@ pub fn close( /// Returns a list of all the .env files present in the database. /// The caller is responsible for freeing memory -fn list(self: @This(), gpa: std.mem.Allocator) ![]EnvFile { - var stmt = self.sql_db.prepare( +fn list(self: *@This(), gpa: std.mem.Allocator) ![]EnvFile { + var stmt = try self.sql_db.prepare( "select path, remotes, sha256, contents from envr_env_files", ); defer stmt.deinit(); - return stmt.all([]const EnvFile, gpa, .{}, .{}); + return stmt.all(EnvFile, gpa, .{}, .{}); } const EnvFile = struct { // TODO: Should use file_name in the struct and derive from the path. path: []const u8, - /// dir is derived from Path, and is not stored in the database. - dir: []const u8, - remotes: [][]const u8, + + // /// dir is derived from Path, and is not stored in the database. + // dir: []const u8, + + /// JSON encoded list of strings + remotes: []const u8, sha256: []const u8, contents: []const u8, }; @@ -269,7 +284,6 @@ test "Closing a fresh database does not create a file" { var tmp_dir = std.testing.tmpDir(.{}); defer tmp_dir.cleanup(); - // @compileLog(@typeInfo(std.Io.File.Permissions)); try tmp_dir.dir.createDir(io, "home", .default_dir); try tmp_dir.dir.createDir(io, "tmp", .default_dir); @@ -304,3 +318,67 @@ test "Closing a fresh database does not create a file" { // test "Closing an unmodified database does not update the file" {} // test "Closing a modified database does create a file" {} + +test "list displays the database's keys" { + const io = std.testing.io; + const gpa = std.testing.allocator; + + var tmp_dir = std.testing.tmpDir(.{}); + defer tmp_dir.cleanup(); + + try tmp_dir.dir.createDir(io, "home", .default_dir); + try tmp_dir.dir.createDir(io, "home/.envr", .default_dir); + try tmp_dir.dir.createDir(io, "tmp", .default_dir); + + const tmp_dir_path = try tmp_dir.dir.realPathFileAlloc(io, ".", gpa); + defer gpa.free(tmp_dir_path); + + const home = try std.fs.path.join(gpa, &.{ tmp_dir_path, "home" }); + defer gpa.free(home); + const tmp = try std.fs.path.join(gpa, &.{ tmp_dir_path, "tmp" }); + defer gpa.free(tmp); + + // TODO: Get rid of direct access + const db_path = try std.fs.path.join(gpa, &.{ home, ".envr", "data.age" }); + defer gpa.free(db_path); + + try std.Io.Dir.cwd().copyFile( + "fixtures/encrypted-single-file.db.age", + tmp_dir.dir, + "home/.envr/data.age", + io, + .{}, + ); + + // Asserts file existence + try tmp_dir.dir.access(io, db_path, .{ .read = true }); + + // TODO: Pass testing keys + const config: Config = .{ + .keys = &.{.from_pub_path("fixtures/insecure-test-key.pub")}, + }; + var db: @This() = try .open(io, gpa, .{ + .config = config, + .home = home, + .tmp = tmp, + }); + + const env_files = try db.list(gpa); + try std.testing.expectEqual(1, env_files.len); + + var hasher = std.crypto.hash.sha2.Sha256.init(.{}); + + for (env_files) |file| { + try std.testing.expectEqualSlices(u8, "", file.path); + try std.testing.expectEqualSlices(u8, "", file.contents); + try std.testing.expectEqualSlices(u8, "", file.remotes); + + hasher.update(file.contents); + const hash = hasher.finalResult(); + try std.testing.expectEqualSlices(u8, &hash, file.sha256); + } else { + return error.TestUnexpectedResult; + } + + try db.close(io, gpa, .{ .home = home, .tmp = tmp }); +} diff --git a/zig-vendor/zig-sqlite/sqlite.zig b/zig-vendor/zig-sqlite/sqlite.zig index 1702a0b..b349f4b 100644 --- a/zig-vendor/zig-sqlite/sqlite.zig +++ b/zig-vendor/zig-sqlite/sqlite.zig @@ -2257,7 +2257,7 @@ pub fn Statement(comptime opts: StatementOptions, comptime query: anytype) type pub fn all(self: *Self, comptime Type: type, allocator: mem.Allocator, options: QueryOptions, values: anytype) ![]Type { var iter = try self.iteratorAlloc(Type, allocator, values); - var rows: std.ArrayList(Type) = .{}; + var rows: std.ArrayList(Type) = .empty; while (try iter.nextAlloc(allocator, options)) |row| { try rows.append(allocator, row); }