A KV store using a remote git repository in memory.
Find a file
Romain Calascibetta b5fa25d9a5 Implement the batch function according to the documentation
This implementation is much more close to the documentation & fold all
changes into one commit. Then, it pushes this commit remotely. This
commit deleted local changes which complexify the codebase for a
questionable interest. As the documentation said, any changes are
delayed and not directly "committed" until the end of the given
function. For instance:
> batch
> set /bar "Bar"
> exists /bar
/bar does not exists

is an expected behavior. Only after a quit (which delimit the end of the
batch process), /bar will be committed and will exist!
2022-10-29 21:18:10 +02:00
app Implement the batch function according to the documentation 2022-10-29 21:18:10 +02:00
src Implement the batch function according to the documentation 2022-10-29 21:18:10 +02:00
test Implement the batch function according to the documentation 2022-10-29 21:18:10 +02:00
.gitignore Functorize git-kv with Pclock to save the right time when we commit 2022-10-19 13:00:04 +02:00
.ocamlformat Functorize git-kv with Pclock to save the right time when we commit 2022-10-19 13:00:04 +02:00
CHANGES.md initial 2022-09-20 13:13:46 +02:00
dune-project Implement the batch function according to the documentation 2022-10-29 21:18:10 +02:00
git-kv.opam Delete useless pin-depends, everything were released 2022-10-21 16:47:53 +02:00
LICENSE.md initial 2022-09-20 13:13:46 +02:00
README.md Rename batch to change_and_push and re-instantiate batch as a noop function 2022-10-28 16:38:32 +02:00

Git-kv, a simple Key-Value store synchronized with a Git repository

This library is a simple implementation of a Git repository that can be read and/or modified. It offers two ways to create such a local repository:

  1. The local repository can be created in a serialized state
  2. The local repository can be created from a remote repository

The first method has the advantage of not requiring an internet connection. The serialized state can be created with the mgit tool:

$ mgit https://github.com/mirage/mirage <<EOF
> save db.pack
> quit
$ ls db.pack
db.pack

The disadvantage is that the serialized state may be out of sync with the state of the remote repository. In this case, the user has access to the pull function, which allows the internet state of the local repository to be re-synchronised with the remote repository.

let contents_of_file filename =
  let ic = open_in filename in
  let ln = in_channel_length ic in
  let rs = Bytes.create ln in
  really_input ic rs 0 ln ;
  Bytes.unsafe_to_string rs

let _ =
  Git_kv.of_octets ctx 
    ~remote:"git@github.com:mirage/mirage.git"
    (contents_of_file "db.pack") >>= fun t ->
  Git_kv.pull t >>= fun diff ->
  ...

The second method initiates a connection to the remote repository in order to download its state and reproduce a synchronised internal state. The type of connections supported are described in the given ctx. We recommend the tutorial about Mimic to understand its use.

let _ =
  Git_kv.connect ctx "git@github.com:mirage/mirage.git" >>= fun t ->
  ...

The user can manipulate the repository as an RW repository. Any change to the repository requires a new commit. These changes will be sent to the remote repository by default. If the user does not want to push modifications, they can use Git_kv.Make.Local which provide functions without push. If the user knows that they will do many changes and they don't want to change all of them and do a push only at the end, they can use Git_kv.Make.change_and_push.

module Store = Git_kv.Make (Pclock)

let new_file_locally_and_remotely t =
  Store.set t Mirage_kv.Key.(empty / "foo") "foo" >>= fun () ->
  ...

let new_file_locally t =
  Git_kv.pull t >>= fun _diff ->
  Store.Local.set t Mirage_kv.Key.(empty / "foo") "foo" >>= fun () ->
  ...

let push_operations t =
  Store.change_and_push t @@ fun t ->
  Store.set t Mirage_kv.Key.(empty / "bar") "bar" >>= fun () ->
  Store.remove t Mirage_kv.Key.(empty / "foo")