231
237
232
238
(* --- accounts --- *)
233
239
240
+
Added:
(* Create the account in one transaction: check the name is free, take the next
241
+
Added:
id, and insert, all under SQLite's write lock. The id comes from the table
242
+
Added:
itself on every call, never from a process-local counter, so two concurrent
243
+
Added:
registrations cannot mint the same id and a file edited outside this process
244
+
Added:
cannot drift from an in-memory count. The UNIQUE constraint on username is
245
+
Added:
the final arbiter; the transaction makes the check-then-insert atomic. *)
234
246
let create_trainee t ~username ~credential =
235
247
let username_s = Trainee.username_to_string username in
236
248
let credential_s = Trainee.credential_to_hash credential in
237
249
run t (fun (module Db : Caqti_lwt.CONNECTION) ->
238
-
Removed:
Db.find_opt Q.trainee_by_username username_s)
239
-
Removed:
>>= function
240
-
Removed:
| Some _ -> Lwt.return (Error `Username_taken)
241
-
Removed:
| None ->
242
-
Removed:
let id = Printf.sprintf "t%d" t.next_trainee in
243
-
Removed:
t.next_trainee <- t.next_trainee + 1;
244
-
Removed:
run t (fun (module Db : Caqti_lwt.CONNECTION) ->
245
-
Removed:
Db.exec Q.insert_trainee (id, username_s, credential_s))
246
-
Removed:
>|= fun () -> Ok { Trainee.id = Trainee.id id; username; credential }
250
+
Added:
let open Lwt_result.Syntax in
251
+
Added:
Db.with_transaction (fun () ->
252
+
Added:
let* existing = Db.find_opt Q.trainee_by_username username_s in
253
+
Added:
match existing with
254
+
Added:
| Some _ -> Lwt_result.return (Error `Username_taken)
255
+
Added:
| None ->
256
+
Added:
let* next = Db.find Q.next_trainee () in
257
+
Added:
let id = Printf.sprintf "t%d" next in
258
+
Added:
let* () =
259
+
Added:
Db.exec Q.insert_trainee (id, username_s, credential_s)
260
+
Added:
in
261
+
Added:
Lwt_result.return
262
+
Added:
(Ok { Trainee.id = Trainee.id id; username; credential })))
247
263
248
264
let trainee_of_row (id, username, credential) =
249
265
match Trainee.username username with