Irmin Store . Fetch all the values from the store

Hi,
I am trying out the example given fo irmin Store setup.

open Lwt.Infix

(* Irmin store with string contents *)
module Store = Irmin_unix.Git.FS.KV(Irmin.Contents.String)

(* Database configuration *)
let config = Irmin_git.config ~bare:true "/tmp/irmin/test"

(* Commit author *)
let author = "Example <example@example.com>"

(* Commit information *)
let info fmt = Irmin_unix.info ~author fmt

let main =
    (* Open the repo *)
    Store.Repo.v config >>=

    (* Load the master branch *)
    Store.master >>= fun t ->

    (* Set key "foo/bar" to "testing 123" *)
    Store.set t ~info:(info "Updating foo/bar") ["foo"; "bar"; key] "testing 123" >>= fun () ->

    (* Get key "foo/bar" and print it to stdout *)
    Store.get t ["foo"; "bar"] >|= fun x ->
    Printf.printf "foo/bar => '%s'\n" x

(* Run the program *)
let () = Lwt_main.run main

If the key and the value differs every time, I want to know if there is any way if I can fetch all the key value pairs stored in the path foo/bar

1 Like

This is possible via Store.get_tree. Once you have a tree, you can find the keys of its children with Store.Tree.list and get the children themselves with Store.Tree.get.

Something like:

(** Get the bindings in the tree at [root] *)
let bindings store root =
  Store.get_tree store root >>= fun tree ->
  Store.Tree.list tree >>= fun children ->

  (* Discard subtrees from the list *)
  List.filter_map (function 
     | (key, `Contents) -> Some key 
     | (_, `Node) -> None)) children

  (* Get remaining K/V pairs *)
  |> Lwt_list.map_s (fun k -> Store.Tree.get k >|= fun v -> (k, v))

Generally, if you want to do anything more complicated than getting/setting individual contents in the store, you should be using the Tree API.

Hi @CraigFe I am getting the below mentioned error.

18 |   Store.Tree.list tree >>= fun children ->
       ^^^^^^^^^^^^^^^^^^^^
Error: This expression has type
         Store.key -> (string * [ `Contents | `Node ]) list Lwt.t
       but an expression was expected of type 'a Lwt.t

Looks like you need to pass the empty key there to mean “get the bindings at the root of this tree”.

Store.Tree.list tree []

@CraigFe

program:
open Lwt.Infix

(* Irmin store with string contents *)
module Store = Irmin_unix.Git.FS.KV(Irmin.Contents.String)

(* Database configuration *)
let config = Irmin_git.config ~bare:true "/tmp/irmin/test"

(* Commit author *)
let author = "Example <example@example.com>"

(* Commit information *)
let info fmt = Irmin_unix.info ~author fmt

(** Get the bindings in the tree at [root] *)
let bindings store root =
  Store.get_tree store root >>= fun tree ->
  Store.Tree.list tree [] |> fun children ->
  List.filter_map (function 
     | (key, `Contents) -> Some key 
     | (_, `Node) -> None) children

  (* Get remaining K/V pairs *)
  |> Lwt_list.map_s (fun k -> Store.Tree.get k >|= fun v -> (k, v)) |>
    Lwt.return

    
    

let setter ()=
    (* Open the repo *)
    Store.Repo.v config >>=

    (* Load the master branch *)
    Store.master >>= fun t ->

    (* Set key "foo/bar" to "testing 123" *)
    Store.set t ~info:(info "Updating foo/bar") ["foo"; "bar"] "testing 123" >>= fun () ->
    
    print_endine "ss";
    let xyzz = bindings t ["foo"] in
    print_endline xyzz;
    ()





(* Run the program *)
let () = setter () 

Error:

File "unikernel.ml", line 21, characters 27-35:
21 |      | (_, `Node) -> None) children
                                ^^^^^^^^
Error: This expression has type (string * [ `Contents | `Node ]) list Lwt.t
       but an expression was expected of type
         ('a * [< `Contents | `Node ]) list

You need to bind the result of Store.Tree.list as I did in my original example, otherwise you’re trying to list map over a thread.

I suggest reading one of the several Lwt tutorials that exist out there if you’re unused to this sort of programming.

Thanks . I fixed the previous issue. Sorry for bothering you again but I am getting another error.

File "unikernel.ml", line 35, characters 30-46:
35 |   |> Lwt_list.map_s (fun k -> Store.Tree.get k >|= fun v -> (k, v))
                                   ^^^^^^^^^^^^^^^^
Error: This expression has type Store.key -> string Lwt.t
       but an expression was expected of type 'a Lwt.t

Oops, you’ll need to pass the tree there again… (Otherwise, what tree are you getting from?)

Store.Tree.get tree k

Still doesn’t work.

code:

let bindings store root =
  Store.get_tree store root >>= fun tree ->
  Store.Tree.list tree [] >>= fun children ->

  (* Discard subtrees from the list *)
  List.filter_map (function 
     | (key, `Contents) -> Some key 
     | (_, `Node) -> None) children

  (* Get remaining K/V pairs *)
  |> Lwt_list.map_s (fun k -> Store.Tree.get tree k >|= fun v -> (k, v))

Error:

File "unikernel.ml", line 35, characters 5-72:
35 |   |> Lwt_list.map_s (fun k -> Store.Tree.get tree k >|= fun v -> (k, v))
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error: This expression has type
         Store.key list -> (Store.key * string) list Lwt.t
       but an expression was expected of type string list -> 'a
       Type Store.key = string list is not compatible with type string
Store.Tree.get tree [ k ]

since get takes a path and not a step.

I think you may have taken my hastily-typed sketch of an answer more literally than was intended :wink: I encourage you to read the documentation for these functions and talk to the typechecker until the two of you reach some sort of agreement :slightly_smiling_face: If you find the documentation lacking, suggestions are welcome.

ok. I am new to both OCaml and Irmin. After the example in the readme file, it is a little bit confusing to start with the documentation. More examples with comments would be helpful. But this discussion forum is helpful. Thank you @CraigFe

1 Like