package sihl-storage

  1. Overview
  2. Docs

Source file sihl_storage.ml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
open Lwt.Syntax

let log_src = Logs.Src.create "sihl.service.storage"

module Logs = (val Logs.src_log log_src : Logs.LOG)

module Make (Repo : Repo.Sig) : Sihl_contract.Storage.Sig = struct
  let find_opt ~id = Repo.get_file ~id

  let find ~id =
    let* file = Repo.get_file ~id in
    match file with
    | None -> raise (Sihl_contract.Storage.Exception ("File not found with id " ^ id))
    | Some file -> Lwt.return file
  ;;

  let delete ~id =
    let* file = find ~id in
    let blob_id = Sihl_type.Storage_stored.blob file in
    let* () = Repo.delete_file ~id:file.file.id in
    Repo.delete_blob ~id:blob_id
  ;;

  let upload_base64 ~file ~base64 =
    let blob_id = Sihl_type.Database.Id.random () |> Sihl_type.Database.Id.to_string in
    let* blob =
      match Base64.decode base64 with
      | Error (`Msg msg) ->
        Logs.err (fun m ->
            m "Could not upload base64 content of file %a" Sihl_type.Storage_file.pp file);
        raise (Sihl_contract.Storage.Exception msg)
      | Ok blob -> Lwt.return blob
    in
    let* () = Repo.insert_blob ~id:blob_id ~blob in
    let stored_file = Sihl_type.Storage_stored.make ~file ~blob:blob_id in
    let* () = Repo.insert_file ~file:stored_file in
    Lwt.return stored_file
  ;;

  let update_base64 ~file ~base64 =
    let blob_id = Sihl_type.Storage_stored.blob file in
    let* blob =
      match Base64.decode base64 with
      | Error (`Msg msg) ->
        Logs.err (fun m ->
            m
              "Could not upload base64 content of file %a"
              Sihl_type.Storage_stored.pp
              file);
        raise (Sihl_contract.Storage.Exception msg)
      | Ok blob -> Lwt.return blob
    in
    let* () = Repo.update_blob ~id:blob_id ~blob in
    let* () = Repo.update_file ~file in
    Lwt.return file
  ;;

  let download_data_base64_opt ~file =
    let blob_id = Sihl_type.Storage_stored.blob file in
    let* blob = Repo.get_blob ~id:blob_id in
    match Option.map Base64.encode blob with
    | Some (Error (`Msg msg)) ->
      Logs.err (fun m ->
          m "Could not get base64 content of file %a" Sihl_type.Storage_stored.pp file);
      raise (Sihl_contract.Storage.Exception msg)
    | Some (Ok blob) -> Lwt.return @@ Some blob
    | None -> Lwt.return None
  ;;

  let download_data_base64 ~file =
    let blob_id = Sihl_type.Storage_stored.blob file in
    let* blob = Repo.get_blob ~id:blob_id in
    match Option.map Base64.encode blob with
    | Some (Error (`Msg msg)) ->
      Logs.err (fun m ->
          m "Could not get base64 content of file %a" Sihl_type.Storage_stored.pp file);
      raise (Sihl_contract.Storage.Exception msg)
    | Some (Ok blob) -> Lwt.return blob
    | None ->
      raise
        (Sihl_contract.Storage.Exception
           (Format.asprintf
              "File data not found for file %a"
              Sihl_type.Storage_stored.pp
              file))
  ;;

  let start () = Lwt.return ()
  let stop () = Lwt.return ()
  let lifecycle = Sihl_core.Container.Lifecycle.create "storage" ~start ~stop

  let register () =
    Repo.register_migration ();
    Repo.register_cleaner ();
    Sihl_core.Container.Service.create lifecycle
  ;;
end

module Repo = Repo
OCaml

Innovation. Community. Security.