tiny.sql.repository
Defined in tiny.sql.
API (1)
Actions
Public operations.
Source
Source: lib/sql/src/repository/flow.zig:7
zig
pub fn Repository(comptime Sql: type, comptime Policy: type) type { const branch = Sql.branch; const history = Sql.history; const sync = Sql.sync; const version = Sql.version; return struct { const Database = Policy.Database; const Remote = remote_owner.Owner(Sql, Policy); pub const Transfer = struct { commits: usize = 0, records: usize = 0, applied: bool = false, merged: bool = false, resolved: usize = 0, }; pub const Head = sync.HeadHex; pub const Status = struct { remote: ?[]u8 = null, local_head: Head, remote_head: ?Head = null, ahead: usize = 0, behind: usize = 0, diverged: bool = false, pub fn deinit(self: *Status, allocator: Allocator) void { if (self.remote) |remote_path| allocator.free(remote_path); self.* = undefined; } }; pub const writeRemote = Remote.write; pub const readRemote = Remote.read; pub fn status( allocator: Allocator, db: *Database, remote_store_dir: ?[]const u8, ) !Status { const local_ref = (try (try db.history.full()).ref( Policy.branch_name, )) orelse return error.RefNotFound; var result = Status{ .local_head = sync.headHex(local_ref.target), }; const remote_dir = remote_store_dir orelse return result; result.remote = try allocator.dupe(u8, remote_dir); errdefer result.deinit(allocator); var opened_remote = try Remote.open(allocator, remote_dir); defer opened_remote.deinit(); const related = try sync.historyRelation( allocator, try db.history.full(), &opened_remote.history, Policy.branch_name, ); if (related.remote_head) |remote_head| { result.remote_head = sync.headHex(remote_head); } result.ahead = related.ahead; result.behind = related.behind; result.diverged = related.diverged(); return result; } pub fn push( allocator: Allocator, workspace: *Database.Workspace, db: *Database, remote_store_dir: []const u8, dry_run: bool, ) !Transfer { if (try db.dirty()) return error.SyncDirtyStore; if (dry_run) { var remote_dir = try Remote.openDir(remote_store_dir); defer remote_dir.close(fs_io); if (!Remote.historyExists(remote_dir)) { var names = [_][]const u8{Policy.branch_name}; var pack = try sync.exportRefNames( allocator, try db.history.full(), names[0..], ); defer pack.deinit(); return .{ .commits = pack.commits.len, .records = pack.frames.len, }; } var opened_remote = try Remote.open( allocator, remote_store_dir, ); defer opened_remote.deinit(); const related = try sync.historyRelation( allocator, try db.history.full(), &opened_remote.history, Policy.branch_name, ); const planned = sync.planHistoryTransfer( allocator, try db.history.full(), &opened_remote.history, Policy.branch_name, related, .push, ) catch |err| return mapHistoryPlanError(err); return transferFromPlan(planned); } var remote_dir = try Remote.openDir(remote_store_dir); defer remote_dir.close(fs_io); var lock = try Remote.lock(remote_dir); defer lock.close(fs_io); if (try Remote.needsBootstrap(allocator, remote_dir)) { if (comptime Policy.validate_transitions) { try Policy.validateSnapshot( allocator, db, try db.headHash(), ); } var remote_history = try history.History.open( allocator, remote_dir, .{ .path = Policy.history_name, .recovery = .reject }, ); defer remote_history.deinit(); const stats = sync.pushFastForward( allocator, try db.history.full(), &remote_history, Policy.branch_name, ) catch |err| switch (err) { error.NonFastForward => return error.SyncDiverged, else => return err, }; var remote_db = try Policy.openWrite( allocator, workspace, remote_dir, ); defer remote_db.deinit(); try remote_db.alignToBranchHead(); try afterRemoteAlignment( allocator, remote_store_dir, &remote_db, ); return .{ .commits = stats.commits, .records = stats.records, .applied = true, }; } var remote_db = try Policy.openWrite( allocator, workspace, remote_dir, ); defer remote_db.deinit(); if (try remote_db.dirty()) return error.SyncDirtyStore; const related = try sync.historyRelation( allocator, try db.history.full(), try remote_db.history.full(), Policy.branch_name, ); if (related.upToDate()) { try afterRemoteAlignment( allocator, remote_store_dir, &remote_db, ); return .{}; } if (related.diverged()) return error.SyncDiverged; if (related.behind != 0) return error.SyncRemoteAhead; if (comptime Policy.validate_transitions) { try Policy.validateTransition( allocator, &remote_db, try remote_db.headHash(), db, try db.headHash(), ); } const stats = sync.pushFastForward( allocator, try db.history.full(), try remote_db.history.full(), Policy.branch_name, ) catch |err| switch (err) { error.NonFastForward => return error.SyncDiverged, else => return err, }; try remote_db.alignToBranchHead(); try afterRemoteAlignment( allocator, remote_store_dir, &remote_db, ); return .{ .commits = stats.commits, .records = stats.records, .applied = true, }; } pub fn pull( allocator: Allocator, workspace: *Database.Workspace, db: *Database, remote_store_dir: []const u8, dry_run: bool, ) !Transfer { if (try db.dirty()) return error.SyncDirtyStore; var opened_remote = try Remote.open( allocator, remote_store_dir, ); defer opened_remote.deinit(); var remote_db: ?Database = null; if (comptime @hasDecl(Policy, "openPullDatabase")) { remote_db = try Policy.openPullDatabase( allocator, workspace, opened_remote.dir, ); } defer if (remote_db) |*db_value| db_value.deinit(); const related = try sync.historyRelation( allocator, try db.history.full(), &opened_remote.history, Policy.branch_name, ); if (related.diverged()) { if (try db.pristine()) { if (dry_run) { return transferFromPlan(try sync.planHistoryAdopt( allocator, try db.history.full(), &opened_remote.history, Policy.branch_name, )); } try validateRemoteTransition( allocator, db, if (remote_db) |*db_value| db_value else null, related.remote_head.?, ); return try adopt( allocator, db, &opened_remote.history, related.remote_head.?, ); } if (dry_run) { const planned = try sync.planHistoryAdopt( allocator, try db.history.full(), &opened_remote.history, Policy.branch_name, ); var transfer = transferFromPlan(planned); transfer.merged = true; return transfer; } return try mergePull( allocator, db, &opened_remote.history, related.remote_head.?, ); } if (dry_run) { const planned = sync.planHistoryTransfer( allocator, try db.history.full(), &opened_remote.history, Policy.branch_name, related, .pull, ) catch |err| return mapHistoryPlanError(err); return transferFromPlan(planned); } if (related.upToDate() or related.remote_head == null) return .{}; if (related.behind == 0) return .{}; try validateRemoteTransition( allocator, db, if (remote_db) |*db_value| db_value else null, related.remote_head.?, ); const stats = sync.pullFastForward( allocator, try db.history.full(), &opened_remote.history, Policy.branch_name, ) catch |err| switch (err) { error.NonFastForward => return error.SyncDiverged, else => return err, }; try db.alignToBranchHead(); return .{ .commits = stats.commits, .records = stats.records, .applied = true, }; } pub fn exportPack( allocator: Allocator, db: *Database, pack_path: []const u8, ) !Transfer { var pack = try sync.exportAll(allocator, try db.history.full()); defer pack.deinit(); const bytes = try sync.encodePack(allocator, &pack); defer allocator.free(bytes); var file = try std.Io.Dir.createFileAbsolute( fs_io, pack_path, .{ .truncate = true }, ); defer file.close(fs_io); try file.writePositionalAll(fs_io, bytes, 0); try file.setLength(fs_io, bytes.len); try file.sync(fs_io); return .{ .commits = pack.commits.len, .records = pack.frames.len, .applied = true, }; } pub fn importPack( allocator: Allocator, db: *Database, bytes: []const u8, dry_run: bool, ) !Transfer { if (try db.dirty()) return error.SyncDirtyStore; var pack = try sync.decodePack(allocator, bytes); defer pack.deinit(); const target = sync.packRefTarget( &pack, Policy.branch_name, ) orelse return error.SyncPackBranchMissing; const local_ref = (try (try db.history.full()).ref( Policy.branch_name, )) orelse return error.RefNotFound; if (dry_run) { const missing = try sync.missingPackCounts( try db.history.full(), &pack, ); if (version.same(local_ref.target, target)) return .{}; return transferFromPlan(missing); } const stats = try sync.importObjects(try db.history.full(), &pack); if (version.same(local_ref.target, target)) return .{}; const entries = try (try db.history.full()).commitEntries(allocator); defer allocator.free(entries); if (!try branch.canFastForward( allocator, entries, local_ref.target, target, )) { if (try branch.canFastForward( allocator, entries, target, local_ref.target, )) return .{}; if (!try db.pristine()) { var transfer = try mergeImported(allocator, db, target); transfer.commits = stats.commits; transfer.records = stats.records; return transfer; } try validateImportedTransition( allocator, db, local_ref.target, target, ); try db.adoptBranchHead(target); return .{ .commits = stats.commits, .records = stats.records, .applied = true, }; } try validateImportedTransition( allocator, db, local_ref.target, target, ); try db.fastForwardTo(target); return .{ .commits = stats.commits, .records = stats.records, .applied = true, }; } fn validateRemoteTransition( allocator: Allocator, db: *Database, remote_db: ?*Database, remote_head: version.Hash, ) !void { if (comptime !Policy.validate_transitions) return; comptime { if (!@hasDecl(Policy, "openPullDatabase")) { @compileError( "transition validation requires openPullDatabase", ); } } const target = remote_db orelse unreachable; try Policy.validateTransition( allocator, db, try db.headHash(), target, remote_head, ); } fn validateImportedTransition( allocator: Allocator, db: *Database, current_head: version.Hash, target_head: version.Hash, ) !void { if (comptime !Policy.validate_transitions) return; try Policy.validateTransition( allocator, db, current_head, db, target_head, ); } fn mergePull( allocator: Allocator, db: *Database, remote_history: *const history.History, remote_head: version.Hash, ) !Transfer { var names = [_][]const u8{Policy.branch_name}; var pack = try sync.exportMissingRefNames( allocator, remote_history, try db.history.full(), names[0..], ); defer pack.deinit(); const stats = try sync.importObjects(try db.history.full(), &pack); var transfer = try mergeImported(allocator, db, remote_head); transfer.commits = stats.commits; transfer.records = stats.records; return transfer; } fn afterRemoteAlignment( allocator: Allocator, remote_store_dir: []const u8, db: *Database, ) !void { if (comptime !Policy.reconcile_remote) return; try Policy.afterRemoteAlignment( allocator, remote_store_dir, db, ); } fn mergeImported( allocator: Allocator, db: *Database, remote_head: version.Hash, ) !Transfer { const resolved = try Policy.mergeImported( allocator, db, remote_head, ); return .{ .applied = true, .merged = true, .resolved = resolved, }; } fn adopt( allocator: Allocator, db: *Database, remote_history: *const history.History, target: version.Hash, ) !Transfer { var names = [_][]const u8{Policy.branch_name}; var pack = try sync.exportMissingRefNames( allocator, remote_history, try db.history.full(), names[0..], ); defer pack.deinit(); const stats = try sync.importObjects(try db.history.full(), &pack); try db.adoptBranchHead(target); return .{ .commits = stats.commits, .records = stats.records, .applied = true, }; } fn transferFromPlan(plan: sync.HistoryTransferPlan) Transfer { return .{ .commits = plan.commits, .records = plan.records, }; } fn mapHistoryPlanError(err: anyerror) anyerror { return switch (err) { error.HistoryDiverged => error.SyncDiverged, error.HistoryRemoteAhead => error.SyncRemoteAhead, else => err, }; } };}Source: lib/sql/src/repository/root.zig
zig
const flow = @import("flow.zig");pub const Repository = flow.Repository;Source: lib/sql/src/root.zig:35
zig
pub const repository = @import("repository/root.zig");Complete call list for repository.Repository
16 direct calls.
tiny.sql.branch.canFastForward[function] atlib/sql/src/branch.zig:77tiny.sql.sync.decodePack[function] atlib/sql/src/sync.zig:470tiny.sql.sync.encodePack[function] atlib/sql/src/sync.zig:373tiny.sql.sync.exportAll[function] atlib/sql/src/sync.zig:1126tiny.sql.sync.exportMissingRefNames[function] atlib/sql/src/sync.zig:1150tiny.sql.sync.exportRefNames[function] atlib/sql/src/sync.zig:1132tiny.sql.sync.headHex[function] atlib/sql/src/sync.zig:1264tiny.sql.sync.historyRelation[function] atlib/sql/src/sync.zig:1305tiny.sql.sync.importObjects[function] atlib/sql/src/sync.zig:1210tiny.sql.sync.missingPackCounts[function] atlib/sql/src/sync.zig:1275tiny.sql.sync.packRefTarget[function] atlib/sql/src/sync.zig:1268tiny.sql.sync.planHistoryAdopt[function] atlib/sql/src/sync.zig:1318tiny.sql.sync.planHistoryTransfer[function] atlib/sql/src/sync.zig:1325tiny.sql.sync.pullFastForward[function] atlib/sql/src/sync.zig:1417tiny.sql.sync.pushFastForward[function] atlib/sql/src/sync.zig:1390tiny.sql.version.same[function] atlib/sql/src/version.zig:498
Audit
| Definitions | 2 |
|---|---|
| Public names | 2 |
| Members | 0 |
| Version | 26.7.0 |
| Revision | daab053ee433 |