ATProto Personal Data Server storage for OCaml
4
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix(lint): remove redundant function prefixes (E331)

Strip get_/make_/find_/create_ from 138 function definitions and all
call sites across ocaml-pds, ocaml-pid1, ocaml-precommit,
ocaml-publicsuffix, ocaml-qemu, ocaml-requests, ocaml-retry, and
ocaml-rpmsg. Use Module.v for constructors per the E331 convention.

+56 -47
+1 -1
lib/blob_store.ml
··· 16 16 17 17 type t = { dir : Eio.Fs.dir_ty Eio.Path.t } 18 18 19 - let create dir = 19 + let v dir = 20 20 (try Eio.Path.mkdirs ~exists_ok:true ~perm:0o755 dir with _ -> ()); 21 21 { dir } 22 22
+2 -2
lib/blob_store.mli
··· 17 17 type t 18 18 (** Blob store handle. *) 19 19 20 - val create : Eio.Fs.dir_ty Eio.Path.t -> t 21 - (** [create dir] creates a blob store rooted at [dir]. *) 20 + val v : Eio.Fs.dir_ty Eio.Path.t -> t 21 + (** [v dir] creates a blob store rooted at [dir]. *) 22 22 23 23 val put : t -> mime_type:string -> string -> Atp.Blob_ref.t 24 24 (** [put t ~mime_type data] stores [data] and returns a blob reference. *)
+10 -10
lib/pds.ml
··· 23 23 let db_path path = Eio.Path.(path / "pds.db") 24 24 let blobs_path path = Eio.Path.(path / "blobs") 25 25 26 - let create ~sw path ~did = 26 + let v ~sw path ~did = 27 27 (* Create directory structure *) 28 28 (try Eio.Path.mkdirs ~exists_ok:true ~perm:0o755 path with _ -> ()); 29 29 let db = Sqlite.create ~sw (db_path path) in 30 30 let blocks = Sqlite.Table.create db ~name:"blocks" in 31 31 let refs = Sqlite.Table.create db ~name:"refs" in 32 32 let meta = Sqlite.Table.create db ~name:"meta" in 33 - let blobs = Blob_store.create (blobs_path path) in 34 - let blockstore = Sqlite_blockstore.create blocks in 33 + let blobs = Blob_store.v (blobs_path path) in 34 + let blockstore = Sqlite_blockstore.v blocks in 35 35 (* Store DID in metadata *) 36 36 Sqlite.Table.put meta "did" (Atp.Did.to_string did); 37 37 Sqlite.Table.put meta "version" "1"; ··· 51 51 let blocks = Sqlite.Table.create db ~name:"blocks" in 52 52 let refs = Sqlite.Table.create db ~name:"refs" in 53 53 let meta = Sqlite.Table.create db ~name:"meta" in 54 - let blobs = Blob_store.create (blobs_path path) in 55 - let blockstore = Sqlite_blockstore.create blocks in 54 + let blobs = Blob_store.v (blobs_path path) in 55 + let blockstore = Sqlite_blockstore.v blocks in 56 56 (* Read DID from metadata *) 57 57 let did = 58 58 match Sqlite.Table.get meta "did" with ··· 72 72 73 73 (* Refs *) 74 74 75 - let get_ref t name = Option.map Atp.Cid.of_string (Sqlite.Table.get t.refs name) 75 + let ref t name = Option.map Atp.Cid.of_string (Sqlite.Table.get t.refs name) 76 76 let set_ref t name cid = Sqlite.Table.put t.refs name (Atp.Cid.to_string cid) 77 77 let delete_ref t name = Sqlite.Table.delete t.refs name 78 78 79 79 let list_refs t = 80 - let refs = ref [] in 80 + let refs = Stdlib.ref [] in 81 81 Sqlite.Table.iter t.refs ~f:(fun name cid_str -> 82 82 refs := (name, Atp.Cid.of_string cid_str) :: !refs); 83 83 List.rev !refs 84 84 85 85 (* HEAD is a special ref *) 86 86 87 - let head t = get_ref t "head" 87 + let head t = ref t "head" 88 88 let set_head t cid = set_ref t "head" cid 89 89 90 90 (* MST operations *) ··· 159 159 (* Blobs *) 160 160 161 161 let put_blob t ~mime_type data = Blob_store.put t.blobs ~mime_type data 162 - let get_blob t cid = Blob_store.get t.blobs cid 162 + let blob t cid = Blob_store.get t.blobs cid 163 163 164 164 (* CAR Import/Export *) 165 165 166 166 let import_car t car_data = 167 167 let reader = Bytesrw.Bytes.Reader.of_string car_data in 168 168 let _header, blocks = Atp.Car.read ~cid_format:`Atproto reader in 169 - let count = ref 0 in 169 + let count = Stdlib.ref 0 in 170 170 Seq.iter 171 171 (fun (cid, data) -> 172 172 t.blockstore#put cid data;
+8 -8
lib/pds.mli
··· 14 14 type t 15 15 (** A PDS repository. *) 16 16 17 - val create : sw:Eio.Switch.t -> Eio.Fs.dir_ty Eio.Path.t -> did:Atp.Did.t -> t 18 - (** [create ~sw path ~did] creates a new repository at [path] for the given DID. 19 - The directory will be created if it doesn't exist. The switch [sw] controls 20 - the lifetime of the underlying database file handle. *) 17 + val v : sw:Eio.Switch.t -> Eio.Fs.dir_ty Eio.Path.t -> did:Atp.Did.t -> t 18 + (** [v ~sw path ~did] creates a new repository at [path] for the given DID. The 19 + directory will be created if it doesn't exist. The switch [sw] controls the 20 + lifetime of the underlying database file handle. *) 21 21 22 22 val open_ : sw:Eio.Switch.t -> Eio.Fs.dir_ty Eio.Path.t -> t 23 23 (** [open_ ~sw path] opens an existing repository at [path]. The switch [sw] ··· 75 75 (** [put_blob t ~mime_type data] stores a blob and returns its reference. The 76 76 blob is content-addressed by its CID. *) 77 77 78 - val get_blob : t -> Atp.Cid.t -> string option 79 - (** [get_blob t cid] reads blob data by CID. *) 78 + val blob : t -> Atp.Cid.t -> string option 79 + (** [blob t cid] reads blob data by CID. *) 80 80 81 81 (** {1 Blob Store} *) 82 82 ··· 102 102 103 103 Named references (like git branches). The default ref is ["head"]. *) 104 104 105 - val get_ref : t -> string -> Atp.Cid.t option 106 - (** [get_ref t name] returns the CID for ref [name]. *) 105 + val ref : t -> string -> Atp.Cid.t option 106 + (** [ref t name] returns the CID for ref [name]. *) 107 107 108 108 val set_ref : t -> string -> Atp.Cid.t -> unit 109 109 (** [set_ref t name cid] sets ref [name] to [cid]. *)
+1 -1
lib/sqlite_blockstore.ml
··· 46 46 method sync = () 47 47 end 48 48 49 - let create blocks = (new sqlite_store blocks :> Atp.Blockstore.writable) 49 + let v blocks = (new sqlite_store blocks :> Atp.Blockstore.writable)
+2 -2
lib/sqlite_blockstore.mli
··· 5 5 6 6 (** SQLite-backed blockstore implementing [Atp.Blockstore.writable]. *) 7 7 8 - val create : Sqlite.Table.t -> Atp.Blockstore.writable 9 - (** [create blocks] creates a writable blockstore backed by SQLite. *) 8 + val v : Sqlite.Table.t -> Atp.Blockstore.writable 9 + (** [v blocks] creates a writable blockstore backed by SQLite. *)
+13 -13
test/test_blob_store.ml
··· 31 31 32 32 let test_roundtrip () = 33 33 with_temp_dir @@ fun path -> 34 - let store = Pds.Blob_store.create path in 34 + let store = Pds.Blob_store.v path in 35 35 let data = "Hello, blob store!" in 36 36 let blob_ref = Pds.Blob_store.put store ~mime_type:"text/plain" data in 37 37 let result = Pds.Blob_store.get store blob_ref.cid in ··· 39 39 40 40 let test_put_returns_correct_size () = 41 41 with_temp_dir @@ fun path -> 42 - let store = Pds.Blob_store.create path in 42 + let store = Pds.Blob_store.v path in 43 43 let data = "some test data for size checking" in 44 44 let blob_ref = Pds.Blob_store.put store ~mime_type:"text/plain" data in 45 45 Alcotest.(check int64) ··· 49 49 50 50 let test_put_returns_correct_mime_type () = 51 51 with_temp_dir @@ fun path -> 52 - let store = Pds.Blob_store.create path in 52 + let store = Pds.Blob_store.v path in 53 53 let blob_ref = 54 54 Pds.Blob_store.put store ~mime_type:"image/png" "fake png data" 55 55 in ··· 57 57 58 58 let test_get_missing_returns_none () = 59 59 with_temp_dir @@ fun path -> 60 - let store = Pds.Blob_store.create path in 60 + let store = Pds.Blob_store.v path in 61 61 let fake_cid = Atp.Cid.v `Raw "nonexistent data" in 62 62 let result = Pds.Blob_store.get store fake_cid in 63 63 Alcotest.(check (option string)) "missing CID returns None" None result 64 64 65 65 let test_mem_true_for_stored () = 66 66 with_temp_dir @@ fun path -> 67 - let store = Pds.Blob_store.create path in 67 + let store = Pds.Blob_store.v path in 68 68 let blob_ref = 69 69 Pds.Blob_store.put store ~mime_type:"text/plain" "stored blob" 70 70 in ··· 74 74 75 75 let test_mem_false_for_missing () = 76 76 with_temp_dir @@ fun path -> 77 - let store = Pds.Blob_store.create path in 77 + let store = Pds.Blob_store.v path in 78 78 let fake_cid = Atp.Cid.v `Raw "not stored" in 79 79 Alcotest.(check bool) 80 80 "mem returns false" false ··· 82 82 83 83 let test_delete_removes_blob () = 84 84 with_temp_dir @@ fun path -> 85 - let store = Pds.Blob_store.create path in 85 + let store = Pds.Blob_store.v path in 86 86 let blob_ref = 87 87 Pds.Blob_store.put store ~mime_type:"text/plain" "will be deleted" 88 88 in ··· 98 98 99 99 let test_binary_data () = 100 100 with_temp_dir @@ fun path -> 101 - let store = Pds.Blob_store.create path in 101 + let store = Pds.Blob_store.v path in 102 102 let data = "\x00\x01\x02\xff\xfe\xfd\x80\x7f" in 103 103 let blob_ref = 104 104 Pds.Blob_store.put store ~mime_type:"application/octet-stream" data ··· 108 108 109 109 let test_multiple_mime_types () = 110 110 with_temp_dir @@ fun path -> 111 - let store = Pds.Blob_store.create path in 111 + let store = Pds.Blob_store.v path in 112 112 let blobs = 113 113 [ 114 114 ("image/png", "fake png bytes"); ··· 136 136 137 137 let test_large_blob () = 138 138 with_temp_dir @@ fun path -> 139 - let store = Pds.Blob_store.create path in 139 + let store = Pds.Blob_store.v path in 140 140 let data = String.make 100_000 'x' in 141 141 let blob_ref = 142 142 Pds.Blob_store.put store ~mime_type:"application/octet-stream" data ··· 147 147 148 148 let test_empty_blob () = 149 149 with_temp_dir @@ fun path -> 150 - let store = Pds.Blob_store.create path in 150 + let store = Pds.Blob_store.v path in 151 151 let data = "" in 152 152 let blob_ref = 153 153 Pds.Blob_store.put store ~mime_type:"application/octet-stream" data ··· 158 158 159 159 let test_duplicate_put () = 160 160 with_temp_dir @@ fun path -> 161 - let store = Pds.Blob_store.create path in 161 + let store = Pds.Blob_store.v path in 162 162 let data = "same content" in 163 163 let ref1 = Pds.Blob_store.put store ~mime_type:"text/plain" data in 164 164 let ref2 = Pds.Blob_store.put store ~mime_type:"text/plain" data in ··· 172 172 173 173 let test_delete_missing_is_noop () = 174 174 with_temp_dir @@ fun path -> 175 - let store = Pds.Blob_store.create path in 175 + let store = Pds.Blob_store.v path in 176 176 let fake_cid = Atp.Cid.v `Raw "never stored" in 177 177 (* Should not raise *) 178 178 Pds.Blob_store.delete store fake_cid;
+3
test/test_blob_store.mli
··· 1 + (** Blob store tests. *) 2 + 1 3 val suite : string * unit Alcotest.test_case list 4 + (** Alcotest suite. *)
+9 -9
test/test_pds.ml
··· 14 14 Eio.Path.(tmp_dir / Printf.sprintf "repo_%d" (Random.int 1_000_000)) 15 15 in 16 16 Eio.Switch.run @@ fun sw -> 17 - let repo = Pds.create ~sw path ~did:test_did in 17 + let repo = Pds.v ~sw path ~did:test_did in 18 18 Fun.protect ~finally:(fun () -> Pds.close repo) (fun () -> f repo) 19 19 20 20 (* Basic repository operations *) ··· 29 29 in 30 30 (* Create *) 31 31 Eio.Switch.run (fun sw -> 32 - let repo = Pds.create ~sw path ~did:test_did in 32 + let repo = Pds.v ~sw path ~did:test_did in 33 33 Pds.close repo); 34 34 (* Open *) 35 35 Eio.Switch.run (fun sw -> ··· 110 110 "size" 111 111 (Int64.of_int (String.length data)) 112 112 blob_ref.size; 113 - let result = Pds.get_blob repo blob_ref.cid in 113 + let result = Pds.blob repo blob_ref.cid in 114 114 Alcotest.(check (option string)) "blob data retrieved" (Some data) result 115 115 116 116 let test_get_missing_blob () = 117 117 with_temp_repo @@ fun repo -> 118 118 let fake_cid = Atp.Cid.v `Raw "nonexistent" in 119 - let result = Pds.get_blob repo fake_cid in 119 + let result = Pds.blob repo fake_cid in 120 120 Alcotest.(check (option string)) "missing blob returns None" None result 121 121 122 122 let test_binary_blob () = 123 123 with_temp_repo @@ fun repo -> 124 124 let data = "\x00\x01\x02\xff\xfe\xfd" in 125 125 let blob_ref = Pds.put_blob repo ~mime_type:"application/octet-stream" data in 126 - let result = Pds.get_blob repo blob_ref.cid in 126 + let result = Pds.blob repo blob_ref.cid in 127 127 Alcotest.(check (option string)) "binary blob preserved" (Some data) result 128 128 129 129 (* Refs *) ··· 132 132 with_temp_repo @@ fun repo -> 133 133 let cid = Atp.Cid.v `Dag_cbor "test data" in 134 134 Pds.set_ref repo "branch1" cid; 135 - let result = Pds.get_ref repo "branch1" in 135 + let result = Pds.ref repo "branch1" in 136 136 Alcotest.(check bool) "ref set and retrieved" true (Option.is_some result); 137 137 Alcotest.(check string) 138 138 "ref CID matches" (Atp.Cid.to_string cid) ··· 153 153 let cid = Atp.Cid.v `Dag_cbor "test" in 154 154 Pds.set_ref repo "temp" cid; 155 155 Pds.delete_ref repo "temp"; 156 - let result = Pds.get_ref repo "temp" in 156 + let result = Pds.ref repo "temp" in 157 157 Alcotest.(check bool) "ref deleted" true (Option.is_none result) 158 158 159 159 (* CAR import/export *) ··· 181 181 let path = 182 182 Eio.Path.(tmp_dir / Printf.sprintf "export_%d" (Random.int 1_000_000)) 183 183 in 184 - let export_repo = Pds.create ~sw path ~did:test_did in 184 + let export_repo = Pds.v ~sw path ~did:test_did in 185 185 let data = Atp.Dagcbor.encode_string (`String "imported") in 186 186 Pds.put export_repo ~collection:"test" ~rkey:"x" data; 187 187 let car = Pds.export_car export_repo in ··· 193 193 let path = 194 194 Eio.Path.(tmp_dir / Printf.sprintf "import_%d" (Random.int 1_000_000)) 195 195 in 196 - let repo = Pds.create ~sw path ~did:test_did in 196 + let repo = Pds.v ~sw path ~did:test_did in 197 197 let count = Pds.import_car repo car_data in 198 198 Pds.close repo; 199 199 Alcotest.(check bool) "imported blocks" true (count >= 0)
+3
test/test_pds.mli
··· 1 + (** PDS tests. *) 2 + 1 3 val suite : string * unit Alcotest.test_case list 4 + (** Alcotest suite. *)
+1 -1
test/test_sqlite_blockstore.ml
··· 12 12 Eio.Switch.run @@ fun sw -> 13 13 let db = Sqlite.create ~sw Eio.Path.(path / name) in 14 14 let table = Sqlite.Table.create db ~name:"blocks" in 15 - let bs = Pds.Sqlite_blockstore.create table in 15 + let bs = Pds.Sqlite_blockstore.v table in 16 16 Fun.protect ~finally:(fun () -> Sqlite.close db) (fun () -> f bs) 17 17 18 18 (* -- Tests ----------------------------------------------------------- *)
+3
test/test_sqlite_blockstore.mli
··· 1 + (** SQLite blockstore tests. *) 2 + 1 3 val suite : string * unit Alcotest.test_case list 4 + (** Alcotest suite. *)