package MlFront_Cache

  1. Overview
  2. Docs

Source file TblEntries.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
100
101
102
103
104
105
106
107
108
109
110
111
112
(** {1 STORAGETYPE_entries} *)

open Sqlite3Ops

let entry_type_int64 = function `File -> 1L | `Directory -> 2L

module Stmts = struct
  type t = { storagetype : StorageType.t }

  let create storagetype = { storagetype }

  let ddl_CREATE_TABLE { storagetype } =
    Printf.sprintf
      {|
CREATE TABLE IF NOT EXISTS %s_entries (
  category TEXT,
  key TEXT,
  entry_type INTEGER, -- 1 is file, 2 is directory
  created_at_epochsec INTEGER,
  last_modified_at_epochsec INTEGER,
  last_accessed_at_epochsec INTEGER,
  path_relto_cachedir TEXT, -- the relative path from (Xdg.cachedir/dkcoder) to the cache file; never erase anything outside of that
  file_size INTEGER, -- zero (0) unless entry_type = 1 (file)
  PRIMARY KEY (category, key)
) STRICT
|}
      (StorageType.name storagetype)

  let ddl_UPGRADE_TABLE_V1 { storagetype } =
    Printf.sprintf
      {|
    ALTER TABLE %s_entries RENAME COLUMN path_relto_cachedir TO path_relto_storagedir
    |}
      (StorageType.name storagetype)

  let dml_UPSERT_INTO { storagetype } =
    Printf.sprintf
      {|
INSERT INTO %s_entries (category, key, entry_type,
  created_at_epochsec, last_modified_at_epochsec, last_accessed_at_epochsec,
  path_relto_storagedir, file_size)
VALUES (:category, :key, :entry_type,
  unixepoch(), unixepoch(), unixepoch(), :path_relto_storagedir, :file_size)
ON CONFLICT DO UPDATE SET
    last_modified_at_epochsec = unixepoch(),
    last_accessed_at_epochsec = unixepoch(),
    path_relto_storagedir = :path_relto_storagedir,
    file_size = :file_size
|}
      (StorageType.name storagetype)

  let dml_UPDATE_last_accessed_at_WHERE_category_key { storagetype } =
    Printf.sprintf
      {|
UPDATE %s_entries
SET last_accessed_at_epochsec = unixepoch()
WHERE category = :category AND key = :key
|}
      (StorageType.name storagetype)

  let dml_DELETE_WHERE_category_key { storagetype } =
    Printf.sprintf
      {|
DELETE FROM %s_entries
WHERE category = :category AND key = :key
|}
      (StorageType.name storagetype)

  let sql_SELECT_WHERE_category_key { storagetype } =
    Printf.sprintf
      {|
SELECT path_relto_storagedir FROM %s_entries
WHERE category = :category AND key = :key
|}
      (StorageType.name storagetype)
end

let create_table_if_not_exists_v1 ~db ~storagetype =
  let stmts = { Stmts.storagetype } in
  let name = StorageType.name storagetype in
  exec_ddl_exn
    ~errbrief:(Printf.sprintf "Could not CREATE TABLE %s_entries." name)
    db
    (Stmts.ddl_CREATE_TABLE stmts);
  Ok ()

let upgrade_table_v2 ~db ~storagetype =
  let stmts = { Stmts.storagetype } in
  let name = StorageType.name storagetype in
  exec_ddl_exn
    ~errbrief:(Printf.sprintf "Could not ALTER TABLE %s_entries." name)
    db
    (Stmts.ddl_UPGRADE_TABLE_V1 stmts);
  Ok ()

(** Create the [STORAGETYPE_entries] table *)
let upgrade_table ~db ~schema_version ~storagetype =
  let starti =
    match schema_version with None -> 0 | Some sv -> Int64.to_int sv
  in
  let exception ResultErr in
  let ok = function Ok v -> v | Error `ErrorCaptured -> raise ResultErr in
  try
    for i = starti to 2 do
      match i with
      | 1 ->
          create_table_if_not_exists_v1 ~db ~storagetype |> ok;
          upgrade_table_v2 ~db ~storagetype |> ok
      | _ -> ()
    done;
    Ok ()
  with ResultErr -> Error `ErrorCaptured
OCaml

Innovation. Community. Security.