support for mirage-kv 6.0.0 (#27)
Reviewed-on: https://git.robur.io/robur/git-kv/pulls/27
This commit is contained in:
parent
eab6bf4e3c
commit
d27fd751e1
4 changed files with 56 additions and 27 deletions
|
@ -74,8 +74,8 @@ let list ~quiet store key =
|
||||||
Store.list store key >>= function
|
Store.list store key >>= function
|
||||||
| Ok lst when not quiet ->
|
| Ok lst when not quiet ->
|
||||||
List.iter (fun (name, k) -> match k with
|
List.iter (fun (name, k) -> match k with
|
||||||
| `Dictionary -> Fmt.pr "d %s\n%!" name
|
| `Dictionary -> Fmt.pr "d %a\n%!" Mirage_kv.Key.pp name
|
||||||
| `Value -> Fmt.pr "- %s\n%!" name) lst ;
|
| `Value -> Fmt.pr "- %a\n%!" Mirage_kv.Key.pp name) lst ;
|
||||||
Lwt.return (Ok 0)
|
Lwt.return (Ok 0)
|
||||||
| Ok _ -> Lwt.return (Ok 0)
|
| Ok _ -> Lwt.return (Ok 0)
|
||||||
| Error err ->
|
| Error err ->
|
||||||
|
|
|
@ -11,7 +11,7 @@ depends: [
|
||||||
"ocaml" {>= "4.08.0"}
|
"ocaml" {>= "4.08.0"}
|
||||||
"dune" {>= "2.0.0"}
|
"dune" {>= "2.0.0"}
|
||||||
"git" {>= "3.9.0"}
|
"git" {>= "3.9.0"}
|
||||||
"mirage-kv" {>= "4.0.0"}
|
"mirage-kv" {>= "6.0.0"}
|
||||||
"carton" {>= "0.6.0"}
|
"carton" {>= "0.6.0"}
|
||||||
"fmt" {>= "0.8.7"}
|
"fmt" {>= "0.8.7"}
|
||||||
"mirage-clock"
|
"mirage-clock"
|
||||||
|
|
|
@ -346,13 +346,16 @@ module Make (Pclock : Mirage_clock.PCLOCK) = struct
|
||||||
type nonrec t = t
|
type nonrec t = t
|
||||||
type key = Mirage_kv.Key.t
|
type key = Mirage_kv.Key.t
|
||||||
|
|
||||||
type error = Mirage_kv.error
|
type error = [ `Msg of string | Mirage_kv.error ]
|
||||||
type write_error = [ `Msg of string
|
type write_error = [ `Msg of string
|
||||||
| `Hash_not_found of Digestif.SHA1.t
|
| `Hash_not_found of Digestif.SHA1.t
|
||||||
| `Reference_not_found of Git.Reference.t
|
| `Reference_not_found of Git.Reference.t
|
||||||
| Mirage_kv.write_error ]
|
| Mirage_kv.write_error ]
|
||||||
|
|
||||||
let pp_error ppf = Mirage_kv.pp_error ppf
|
let pp_error ppf = function
|
||||||
|
| #Mirage_kv.error as err -> Mirage_kv.pp_error ppf err
|
||||||
|
| `Msg msg -> Fmt.string ppf msg
|
||||||
|
|
||||||
let disconnect _t = Lwt.return_unit
|
let disconnect _t = Lwt.return_unit
|
||||||
|
|
||||||
let pp_write_error ppf = function
|
let pp_write_error ppf = function
|
||||||
|
@ -387,12 +390,15 @@ module Make (Pclock : Mirage_clock.PCLOCK) = struct
|
||||||
|
|
||||||
let get_partial t key ~offset ~length =
|
let get_partial t key ~offset ~length =
|
||||||
let open Lwt_result.Infix in
|
let open Lwt_result.Infix in
|
||||||
get t key >|= fun data ->
|
get t key >>= fun data ->
|
||||||
if String.length data < offset then
|
let off = Optint.Int63.to_int offset in
|
||||||
""
|
if off < 0 then
|
||||||
|
Lwt_result.fail (`Msg "offset does not fit into integer")
|
||||||
|
else if String.length data < off then
|
||||||
|
Lwt_result.return ""
|
||||||
else
|
else
|
||||||
let l = min length (String.length data - offset) in
|
let l = min length (String.length data - off) in
|
||||||
String.sub data offset l
|
Lwt_result.return (String.sub data off l)
|
||||||
|
|
||||||
let list t key =
|
let list t key =
|
||||||
let open Lwt.Infix in
|
let open Lwt.Infix in
|
||||||
|
@ -404,11 +410,15 @@ module Make (Pclock : Mirage_clock.PCLOCK) = struct
|
||||||
| Some tree ->
|
| Some tree ->
|
||||||
Store.read_exn t.store tree >>= function
|
Store.read_exn t.store tree >>= function
|
||||||
| Tree t ->
|
| Tree t ->
|
||||||
Lwt_list.map_p (fun { Git.Tree.perm; name; _ } -> match perm with
|
let r =
|
||||||
| `Commit | `Dir -> Lwt.return (name, `Dictionary)
|
List.map (fun { Git.Tree.perm; name; _ } ->
|
||||||
| `Everybody | `Exec | `Normal -> Lwt.return (name, `Value)
|
Mirage_kv.Key.add key name,
|
||||||
| `Link -> failwith "Unimplemented link follow")
|
match perm with
|
||||||
(Store.Value.Tree.to_list t) >|= Result.ok
|
| `Commit | `Dir -> `Dictionary
|
||||||
|
| `Everybody | `Exec | `Normal | `Link -> `Value)
|
||||||
|
(Store.Value.Tree.to_list t)
|
||||||
|
in
|
||||||
|
Lwt.return (Ok r)
|
||||||
| _ -> Lwt.return (Error (`Dictionary_expected key))
|
| _ -> Lwt.return (Error (`Dictionary_expected key))
|
||||||
|
|
||||||
let last_modified t key =
|
let last_modified t key =
|
||||||
|
@ -430,9 +440,11 @@ module Make (Pclock : Mirage_clock.PCLOCK) = struct
|
||||||
tz_offset
|
tz_offset
|
||||||
in
|
in
|
||||||
let ts =
|
let ts =
|
||||||
Option.fold ~none:Ptime.epoch ~some:Fun.id (Ptime.of_float_s (Int64.to_float secs))
|
Option.fold
|
||||||
|
~none:Ptime.epoch
|
||||||
|
~some:Fun.id (Ptime.of_float_s (Int64.to_float secs))
|
||||||
in
|
in
|
||||||
Ok (Ptime.(Span.to_d_ps (to_span ts)))
|
Ok ts
|
||||||
| _ -> assert false)
|
| _ -> assert false)
|
||||||
t.head
|
t.head
|
||||||
|
|
||||||
|
@ -445,7 +457,7 @@ module Make (Pclock : Mirage_clock.PCLOCK) = struct
|
||||||
let size t key =
|
let size t key =
|
||||||
let open Lwt_result.Infix in
|
let open Lwt_result.Infix in
|
||||||
get t key >|= fun data ->
|
get t key >|= fun data ->
|
||||||
String.length data
|
Optint.Int63.of_int (String.length data)
|
||||||
|
|
||||||
let author ~now =
|
let author ~now =
|
||||||
{ Git.User.name= "Git KV"
|
{ Git.User.name= "Git KV"
|
||||||
|
@ -540,10 +552,14 @@ module Make (Pclock : Mirage_clock.PCLOCK) = struct
|
||||||
get t key >>= fun contents ->
|
get t key >>= fun contents ->
|
||||||
let len = String.length contents in
|
let len = String.length contents in
|
||||||
let add = String.length chunk in
|
let add = String.length chunk in
|
||||||
let res = Bytes.make (max len (offset + add)) '\000' in
|
let off = Optint.Int63.to_int offset in
|
||||||
Bytes.blit_string contents 0 res 0 len ;
|
if off < 0 then
|
||||||
Bytes.blit_string chunk 0 res offset add ;
|
Lwt_result.fail (`Msg "offset does not fit into integer")
|
||||||
set t key (Bytes.unsafe_to_string res)
|
else
|
||||||
|
let res = Bytes.make (max len (off + add)) '\000' in
|
||||||
|
Bytes.blit_string contents 0 res 0 len ;
|
||||||
|
Bytes.blit_string chunk 0 res off add ;
|
||||||
|
set t key (Bytes.unsafe_to_string res)
|
||||||
|
|
||||||
let remove ?and_commit t key =
|
let remove ?and_commit t key =
|
||||||
let segs = Mirage_kv.Key.segments key in
|
let segs = Mirage_kv.Key.segments key in
|
||||||
|
@ -609,15 +625,27 @@ module Make (Pclock : Mirage_clock.PCLOCK) = struct
|
||||||
remove t source >>= fun () ->
|
remove t source >>= fun () ->
|
||||||
set t dest contents
|
set t dest contents
|
||||||
|
|
||||||
let batch t ?retries:_ f = f t
|
let allocate t key ?last_modified:_ size =
|
||||||
|
let open Lwt.Infix in
|
||||||
|
exists t key >>= function
|
||||||
|
| Error _ as e -> Lwt.return e
|
||||||
|
| Ok Some _ -> Lwt_result.fail (`Already_present key)
|
||||||
|
| Ok None ->
|
||||||
|
let size = Optint.Int63.to_int size in
|
||||||
|
if size < 0 then
|
||||||
|
Lwt_result.fail (`Msg "size does not fit into integer")
|
||||||
|
else
|
||||||
|
let data = String.make size '\000' in
|
||||||
|
set t key data
|
||||||
|
|
||||||
let change_and_push t f =
|
let change_and_push t f =
|
||||||
let open Lwt.Infix in
|
let open Lwt.Infix in
|
||||||
if t.in_closure then
|
if t.in_closure then
|
||||||
Lwt.return_error (`Msg "Nested change_and_push")
|
Lwt.return_error (`Msg "Nested change_and_push")
|
||||||
else
|
else
|
||||||
(* XXX(dinosaure): serialize [batch]. If we do [Lwt.both (batch ..) (batch ..)], they
|
(* XXX(dinosaure): serialize [change_and_push]. If we do
|
||||||
can not run concurrently! The second will waiting the first to finish. *)
|
[Lwt.both (change_and_push ..) (change_and_push ..)], they can not run
|
||||||
|
concurrently! The second will waiting the first to finish. *)
|
||||||
( match t.committed with
|
( match t.committed with
|
||||||
| None -> Lwt.return_unit
|
| None -> Lwt.return_unit
|
||||||
| Some (_tree_root_hash, th) -> th ) >>= fun () ->
|
| Some (_tree_root_hash, th) -> th ) >>= fun () ->
|
||||||
|
@ -627,8 +655,8 @@ module Make (Pclock : Mirage_clock.PCLOCK) = struct
|
||||||
t.committed <- Some (tree_root_hash, th) ;
|
t.committed <- Some (tree_root_hash, th) ;
|
||||||
let t' = { t with in_closure= true } in
|
let t' = { t with in_closure= true } in
|
||||||
f t' >>! fun res ->
|
f t' >>! fun res ->
|
||||||
(* XXX(dinosaure): we assume that only [batch] can reset [t.committed] to [None] and
|
(* XXX(dinosaure): we assume that only [change_and_push] can reset [t.committed] to [None] and
|
||||||
we ensured that [batch] can not be called into [f]. So we are sure that [t'.committed]
|
we ensured that [change_and_push] can not be called into [f]. So we are sure that [t'.committed]
|
||||||
must be [Some _] in anyway. *)
|
must be [Some _] in anyway. *)
|
||||||
let[@warning "-8"] Some (new_tree_root_hash, _) = t'.committed in
|
let[@warning "-8"] Some (new_tree_root_hash, _) = t'.committed in
|
||||||
if Digestif.SHA1.equal new_tree_root_hash tree_root_hash
|
if Digestif.SHA1.equal new_tree_root_hash tree_root_hash
|
||||||
|
|
|
@ -66,6 +66,7 @@ module Make (Pclock : Mirage_clock.PCLOCK) : sig
|
||||||
| `Hash_not_found of Digestif.SHA1.t
|
| `Hash_not_found of Digestif.SHA1.t
|
||||||
| `Reference_not_found of Git.Reference.t
|
| `Reference_not_found of Git.Reference.t
|
||||||
| Mirage_kv.write_error ]
|
| Mirage_kv.write_error ]
|
||||||
|
and type error = [ `Msg of string | Mirage_kv.error ]
|
||||||
|
|
||||||
val change_and_push : t -> (t -> 'a Lwt.t) -> ('a, [> `Msg of string ]) result Lwt.t
|
val change_and_push : t -> (t -> 'a Lwt.t) -> ('a, [> `Msg of string ]) result Lwt.t
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue