diff options
| author | Marcos Magueta <maguetamarcos@gmail.com> | 2026-04-27 13:00:30 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-04-27 13:00:30 -0300 |
| commit | 56492ad5f6f09d8c9f337d42803b64d1b9f0668b (patch) | |
| tree | 0a41825d319fe47e037e2e30ed515c3c2d9b0d7d /lib/dcl | |
| parent | 12f170f438f5909511da2f26c5d33a85acc1fe64 (diff) | |
| download | Sakura-56492ad5f6f09d8c9f337d42803b64d1b9f0668b.tar.gz Sakura-56492ad5f6f09d8c9f337d42803b64d1b9f0668b.zip | |
Introduce Multigroups (#65)
Diffstat (limited to 'lib/dcl')
| -rw-r--r-- | lib/dcl/ast.ml | 2 | ||||
| -rw-r--r-- | lib/dcl/executor.ml | 161 | ||||
| -rw-r--r-- | lib/dcl/sublanguage.ml | 4 |
3 files changed, 90 insertions, 77 deletions
diff --git a/lib/dcl/ast.ml b/lib/dcl/ast.ml index 0b6107f..a55ec19 100644 --- a/lib/dcl/ast.ml +++ b/lib/dcl/ast.ml @@ -10,4 +10,6 @@ type statement = | GetBranchTip of string | UpdateBranchTip of { name : string; hash : string } | Merge of { left : string; right : string; strategy : merge_strategy } + | Use of string + | CreateMultigroup of string [@@deriving sexp] diff --git a/lib/dcl/executor.ml b/lib/dcl/executor.ml index a651067..b83f629 100644 --- a/lib/dcl/executor.ml +++ b/lib/dcl/executor.ml @@ -4,24 +4,24 @@ module Make (Storage : Management.Physical.S with type error = string) = struct module MergeOps = Management.Merge.Make (Storage) (Ops) type error = - | ParseError of string - | BranchError of Error.t - | BranchNotFound of string + | ParseError of string + | BranchError of Error.t + | BranchNotFound of string | NoDatabaseAtHash of Conventions.Hash.t - | StorageError of string - | MergeError of Error.t - | Conflict of string + | StorageError of string + | MergeError of Error.t + | Conflict of string let sexp_of_error e = let open Sexplib.Sexp in match e with - | ParseError s -> List [Atom "parse-error"; Atom s] - | BranchError s -> List [Atom "branch-error"; Error.sexp_of_error s] - | BranchNotFound s -> List [Atom "branch-not-found"; Atom s] - | NoDatabaseAtHash s -> List [Atom "no-database-at-hash"; Atom s] - | StorageError s -> List [Atom "storage-error"; Atom s] - | MergeError s -> List [Atom "merge-error"; Error.sexp_of_error s] - | Conflict s -> List [Atom "conflict"; Atom s] + | ParseError s -> List [ Atom "parse-error"; Atom s ] + | BranchError s -> List [ Atom "branch-error"; Error.sexp_of_error s ] + | BranchNotFound s -> List [ Atom "branch-not-found"; Atom s ] + | NoDatabaseAtHash s -> List [ Atom "no-database-at-hash"; Atom s ] + | StorageError s -> List [ Atom "storage-error"; Atom s ] + | MergeError s -> List [ Atom "merge-error"; Error.sexp_of_error s ] + | Conflict s -> List [ Atom "conflict"; Atom s ] let convert_strategy : Ast.merge_strategy -> Management.Merge.strategy = function @@ -29,71 +29,80 @@ module Make (Storage : Management.Physical.S with type error = string) = struct | Ast.PreferRight -> Management.Merge.PreferRight | Ast.RevertToAncestor -> Management.Merge.RevertToAncestor + type exec_result = + | DbResult of Management.Database.t * string + | Switch of string + | NewMultigroup of string + let execute (storage : Storage.t) (db : Management.Database.t) - (stmt : Ast.statement) : (Management.Database.t * string, error) result = + (stmt : Ast.statement) : (exec_result, error) result = match stmt with - | Ast.CreateBranch { name; hash } -> - let tip = match hash with - | Some h -> h - | None -> db.Management.Database.hash - in - (match Branch.create storage ~name ~tip with - | Error e -> Error (StorageError e) - | Ok () -> Ok (db, "Branch " ^ name ^ " created")) - - | Ast.Checkout branch_name -> - (match Branch.get_tip storage branch_name with - | Error e -> Error (StorageError e) - | Ok None -> Error (BranchNotFound branch_name) - | Ok (Some tip) -> - (match Branch.checkout storage branch_name with - | Error e -> Error (StorageError e) - | Ok () -> - (match Ops.load_database storage tip with - | Error e -> Error (BranchError e) - | Ok None -> Error (NoDatabaseAtHash tip) - | Ok (Some loaded_db) -> - Ok (loaded_db, "HEAD:" ^ branch_name)))) - - | Ast.GetHead -> - (match Branch.get_head storage with - | Error e -> Error (StorageError e) - | Ok None -> Ok (db, "HEAD is unset") - | Ok (Some name) -> Ok (db, "HEAD:" ^ name)) - - | Ast.GetBranchTip name -> - (match Branch.get_tip storage name with - | Error e -> Error (StorageError e) - | Ok None -> Error (BranchNotFound name) - | Ok (Some hash) -> Ok (db, "branch:" ^ name ^ "=" ^ hash)) - - | Ast.UpdateBranchTip { name; hash } -> - (match Branch.update_tip storage ~name ~tip:hash with - | Error e -> Error (StorageError e) - | Ok () -> Ok (db, "Branch " ^ name ^ " updated")) - - | Ast.Merge { left; right; strategy } -> - (match Branch.get_tip storage left, Branch.get_tip storage right with - | Error e, _ | _, Error e -> Error (StorageError e) - | Ok None, _ -> Error (BranchNotFound left) - | _, Ok None -> Error (BranchNotFound right) - | Ok (Some left_tip), Ok (Some right_tip) -> - let strat = convert_strategy strategy in - (match MergeOps.merge ~storage ~strategy:strat ~left_tip ~right_tip with - | Error e -> Error (MergeError e) - | Ok (Management.Merge.Failed conflicts) -> - let msgs = List.map (function - | Management.Merge.TupleConflict { relation; hash } -> - "tuple conflict in " ^ relation ^ " (" ^ hash ^ ")" - | Management.Merge.SchemaConflict r -> "schema conflict in " ^ r - | Management.Merge.ConstraintConflict r -> "constraint conflict in " ^ r - ) conflicts in - Error (Conflict ("Merge failed: " ^ String.concat "; " msgs)) - | Ok (Management.Merge.Clean merged_db) -> - let _ = Branch.update_tip storage ~name:left - ~tip:merged_db.Management.Database.hash in - Ok (merged_db, - "Merged:" ^ right ^ "→" ^ left))) + | Ast.CreateBranch { name; hash } -> ( + let tip = + match hash with Some h -> h | None -> db.Management.Database.hash + in + match Branch.create storage ~name ~tip with + | Error e -> Error (StorageError e) + | Ok () -> Ok (DbResult (db, "Branch " ^ name ^ " created"))) + | Ast.Checkout branch_name -> ( + match Branch.get_tip storage branch_name with + | Error e -> Error (StorageError e) + | Ok None -> Error (BranchNotFound branch_name) + | Ok (Some tip) -> ( + match Branch.checkout storage branch_name with + | Error e -> Error (StorageError e) + | Ok () -> ( + match Ops.load_database storage tip with + | Error e -> Error (BranchError e) + | Ok None -> Error (NoDatabaseAtHash tip) + | Ok (Some loaded_db) -> + Ok (DbResult (loaded_db, "HEAD:" ^ branch_name))))) + | Ast.GetHead -> ( + match Branch.get_head storage with + | Error e -> Error (StorageError e) + | Ok None -> Ok (DbResult (db, "HEAD is unset")) + | Ok (Some name) -> Ok (DbResult (db, "HEAD:" ^ name))) + | Ast.GetBranchTip name -> ( + match Branch.get_tip storage name with + | Error e -> Error (StorageError e) + | Ok None -> Error (BranchNotFound name) + | Ok (Some hash) -> Ok (DbResult (db, "branch:" ^ name ^ "=" ^ hash))) + | Ast.UpdateBranchTip { name; hash } -> ( + match Branch.update_tip storage ~name ~tip:hash with + | Error e -> Error (StorageError e) + | Ok () -> Ok (DbResult (db, "Branch " ^ name ^ " updated"))) + | Ast.Merge { left; right; strategy } -> ( + match (Branch.get_tip storage left, Branch.get_tip storage right) with + | Error e, _ | _, Error e -> Error (StorageError e) + | Ok None, _ -> Error (BranchNotFound left) + | _, Ok None -> Error (BranchNotFound right) + | Ok (Some left_tip), Ok (Some right_tip) -> ( + let strat = convert_strategy strategy in + match + MergeOps.merge ~storage ~strategy:strat ~left_tip ~right_tip + with + | Error e -> Error (MergeError e) + | Ok (Management.Merge.Failed conflicts) -> + let msgs = + List.map + (function + | Management.Merge.TupleConflict { relation; hash } -> + "tuple conflict in " ^ relation ^ " (" ^ hash ^ ")" + | Management.Merge.SchemaConflict r -> + "schema conflict in " ^ r + | Management.Merge.ConstraintConflict r -> + "constraint conflict in " ^ r) + conflicts + in + Error (Conflict ("Merge failed: " ^ String.concat "; " msgs)) + | Ok (Management.Merge.Clean merged_db) -> + let _ = + Branch.update_tip storage ~name:left + ~tip:merged_db.Management.Database.hash + in + Ok (DbResult (merged_db, "Merged:" ^ right ^ "→" ^ left)))) + | Ast.Use multigroup -> Ok (Switch multigroup) + | Ast.CreateMultigroup name -> Ok (NewMultigroup name) end module Memory = Make (Management.Physical.Memory) diff --git a/lib/dcl/sublanguage.ml b/lib/dcl/sublanguage.ml index eab5ecb..7af0703 100644 --- a/lib/dcl/sublanguage.ml +++ b/lib/dcl/sublanguage.ml @@ -16,7 +16,9 @@ module Make (Storage : Management.Physical.S with type error = string) = struct let execute storage db ast = match Exec.execute storage db ast with - | Ok (db, msg) -> Ok (Sublanguage_types.Transition (db, msg)) + | Ok (Exec.DbResult (db, msg)) -> Ok (Sublanguage_types.Transition (db, msg)) + | Ok (Exec.Switch multigroup) -> Ok (Sublanguage_types.SessionSwitch multigroup) + | Ok (Exec.NewMultigroup name) -> Ok (Sublanguage_types.CreateMultigroup name) | Error e -> Error e let sexp_of_error = Exec.sexp_of_error |
