geochan/src/client/db.ml

130 lines
3 KiB
OCaml
Raw Normal View History

2023-12-18 00:45:46 +01:00
open Types
let session : session option ref = ref None
let update_session (v : session) =
session := Some v;
()
let get_session () =
match !session with
| None -> Fmt.failwith "called get_session with uninitialized session"
| Some v -> v
let post_db : (post_id, post) Hashtbl.t = Hashtbl.create 0x1000
let add_post (v : post) =
Hashtbl.replace post_db v.id v;
()
let find_post id =
match Hashtbl.find_opt post_db id with None -> None | Some v -> Some v
let post_db_404 : (post_id, unit) Hashtbl.t = Hashtbl.create 0x100
let post_is_404 id = Hashtbl.mem post_db_404 id
let thread_is_404 id = Hashtbl.mem post_db_404 id
let user_db_404 : (user_id, unit) Hashtbl.t = Hashtbl.create 0x100
let user_is_404 id = Hashtbl.mem user_db_404 id
let catalog : thread list ref = ref []
let update_catalog (v : thread list) =
catalog := v;
()
let get_catalog () = !catalog
let thread_w_reply : Thread_w_reply.t option ref = ref None
let update_thread_w_reply (o : Thread_w_reply.t option) =
Hashtbl.clear post_db;
thread_w_reply := o;
Option.iter (fun v -> List.iter add_post v.Thread_w_reply.reply_l) o;
()
let find_thread_w_reply id =
match !thread_w_reply with
| None -> None
| Some v -> ( match v.op.id = id with false -> None | true -> Some v )
let reports : report list ref = ref []
let update_reports (v : report list) =
reports := v;
()
let get_reports () = !reports
let user : user option ref = ref None
let update_user (v : user option) =
user := v;
()
let find_user id =
match !user with
| None -> None
| Some v -> (
match String.equal v.user_id id with false -> None | true -> Some v )
let clear () =
session := None;
update_catalog [];
update_thread_w_reply None;
update_reports [];
Hashtbl.clear post_db;
Hashtbl.clear post_db_404;
update_user None;
()
let add_post_404 id =
(* in case post is a thread we have to remove id + potential reply_l *)
let to_delete_l =
match find_thread_w_reply id with
| Some v -> List.map (fun p -> p.id) v.reply_l
| None -> [ id ]
in
let filter get_id l =
(* O(n^2) ~~ *)
List.filter (fun v -> not @@ List.mem (get_id v) to_delete_l) l
in
update_catalog (get_catalog () |> filter (fun v -> v.op.id));
update_thread_w_reply
( match find_thread_w_reply id with
| Some _ -> None
| None -> (
match !thread_w_reply with
| None -> None
| Some v ->
let v = { v with reply_l = filter (fun v -> v.id) v.reply_l } in
Some v ) );
update_reports (!reports |> filter (fun r -> r.reported_post.id));
Hashtbl.remove post_db id;
Hashtbl.add post_db_404 id ();
()
let add_thread_404 = add_post_404
let add_user_404 id =
let session = get_session () in
let session =
match session.user_private with
| Some u when String.equal u.user_id id ->
(* dead session here *)
{ session with user_private = None }
| _ -> session
in
update_session session;
begin
match find_user id with Some _ -> update_user None | None -> ()
end;
()