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