Skip to content

Commit b6952d6

Browse files
authored
Update feature branch (#6120)
2 parents 8c3438d + 77dd474 commit b6952d6

28 files changed

+1036
-921
lines changed

dune-project

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -464,16 +464,16 @@ This package provides an Lwt compatible interface to the library.")
464464
(homepage "https://github.com/mirage/ocaml-vhd")
465465
(source (github mirage/ocaml-vhd))
466466
(depends
467-
(ocaml (and (>= "4.02.3") (< "5.0.0")))
467+
(ocaml (>= "4.10.0"))
468468
(alcotest :with-test)
469-
(alcotest-lwt :with-test)
470-
bigarray-compat
471-
(cstruct (< "6.1.0"))
469+
(alcotest-lwt (and :with-test (>= "1.0.0")))
470+
(bigarray-compat (>= "1.1.0"))
471+
(cstruct (>= "6.0.0"))
472472
cstruct-lwt
473473
(fmt :with-test)
474474
(lwt (>= "3.2.0"))
475-
(mirage-block (>= "2.0.1"))
476-
rresult
475+
(mirage-block (>= "3.0.0"))
476+
(rresult (>= "0.7.0"))
477477
(vhd-format (= :version))
478478
(io-page (and :with-test (>= "2.4.0")))
479479
)

ocaml/database/db_cache_types.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ module Row = struct
158158
with Not_found -> raise (DBCache_NotFound ("missing field", key, ""))
159159

160160
let add_defaults g (schema : Schema.Table.t) t =
161+
let schema = Schema.Table.t'_of_t schema in
161162
List.fold_left
162163
(fun t c ->
163164
if not (mem c.Schema.Column.name t) then

ocaml/database/schema.ml

Lines changed: 88 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -96,28 +96,104 @@ module Column = struct
9696
(** only so we can special case set refs in the interface *)
9797
}
9898
[@@deriving sexp]
99+
100+
let name_of t = t.name
99101
end
100102

103+
let tabulate ks ~key_fn =
104+
let tbl = Hashtbl.create 64 in
105+
List.iter (fun c -> Hashtbl.replace tbl (key_fn c) c) ks ;
106+
tbl
107+
108+
let values_of_table tbl = Hashtbl.fold (fun _ v vs -> v :: vs) tbl []
109+
101110
module Table = struct
102-
type t = {name: string; columns: Column.t list; persistent: bool}
111+
type t' = {name: string; columns: Column.t list; persistent: bool}
103112
[@@deriving sexp]
104113

105-
let find name t =
106-
try List.find (fun col -> col.Column.name = name) t.columns
107-
with Not_found ->
108-
raise (Db_exn.DBCache_NotFound ("missing column", t.name, name))
114+
type t = {
115+
name: string
116+
; columns: (string, Column.t) Hashtbl.t
117+
; persistent: bool
118+
}
119+
120+
let t'_of_t : t -> t' =
121+
fun (t : t) ->
122+
let ({name; columns; persistent} : t) = t in
123+
let columns = values_of_table columns in
124+
{name; columns; persistent}
125+
126+
let t_of_t' : t' -> t =
127+
fun (t' : t') ->
128+
let ({name; columns; persistent} : t') = t' in
129+
let columns = tabulate columns ~key_fn:Column.name_of in
130+
{name; columns; persistent}
131+
132+
let sexp_of_t t =
133+
let t' = t'_of_t t in
134+
sexp_of_t' t'
135+
136+
let t_of_sexp s =
137+
let ({name; columns; persistent} : t') = t'_of_sexp s in
138+
let columns = tabulate columns ~key_fn:Column.name_of in
139+
({name; columns; persistent} : t)
140+
141+
let find name (t : t) =
142+
match Hashtbl.find_opt t.columns name with
143+
| Some c ->
144+
c
145+
| _ ->
146+
raise (Db_exn.DBCache_NotFound ("missing column", t.name, name))
147+
148+
let create ~name ~columns ~persistent : t =
149+
let columns =
150+
let tbl = Hashtbl.create 64 in
151+
List.iter (fun c -> Hashtbl.add tbl c.Column.name c) columns ;
152+
tbl
153+
in
154+
{name; columns; persistent}
155+
156+
let name_of t = t.name
109157
end
110158

111159
type relationship = OneToMany of string * string * string * string
112160
[@@deriving sexp]
113161

114162
module Database = struct
115-
type t = {tables: Table.t list} [@@deriving sexp]
163+
type t' = {tables: Table.t list} [@@deriving sexp]
164+
165+
type t = {tables: (string, Table.t) Hashtbl.t}
166+
167+
let t_of_t' : t' -> t =
168+
fun (t' : t') ->
169+
let ({tables} : t') = t' in
170+
let tables = tabulate tables ~key_fn:Table.name_of in
171+
{tables}
172+
173+
let t'_of_t : t -> t' =
174+
fun (t : t) ->
175+
let ({tables} : t) = t in
176+
let tables = values_of_table tables in
177+
{tables}
178+
179+
let sexp_of_t t =
180+
let t' = t'_of_t t in
181+
sexp_of_t' t'
182+
183+
let t_of_sexp s =
184+
let t' = t'_of_sexp s in
185+
t_of_t' t'
116186

117187
let find name t =
118-
try List.find (fun tbl -> tbl.Table.name = name) t.tables
119-
with Not_found ->
120-
raise (Db_exn.DBCache_NotFound ("missing table", name, ""))
188+
match Hashtbl.find_opt t.tables name with
189+
| Some tbl ->
190+
tbl
191+
| _ ->
192+
raise (Db_exn.DBCache_NotFound ("missing table", name, ""))
193+
194+
let of_tables tables =
195+
let tables = tabulate tables ~key_fn:Table.name_of in
196+
{tables}
121197
end
122198

123199
(** indexed by table name, a list of (this field, foreign table, foreign field) *)
@@ -161,7 +237,7 @@ let empty =
161237
{
162238
major_vsn= 0
163239
; minor_vsn= 0
164-
; database= {Database.tables= []}
240+
; database= {Database.tables= Hashtbl.create 64}
165241
; one_to_many= ForeignMap.empty
166242
; many_to_many= ForeignMap.empty
167243
}
@@ -174,7 +250,8 @@ let is_field_persistent schema tblname fldname =
174250
tbl.Table.persistent && col.Column.persistent
175251

176252
let table_names schema =
177-
List.map (fun t -> t.Table.name) (database schema).Database.tables
253+
let tables = (database schema).Database.tables in
254+
Hashtbl.fold (fun k _ ks -> k :: ks) tables []
178255

179256
let one_to_many tblname schema =
180257
(* If there is no entry in the map it means that the table has no one-to-many relationships *)

ocaml/database/test_schemas.ml

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -99,22 +99,35 @@ let schema =
9999
; issetref= false
100100
}
101101
in
102-
let vm_table =
103-
{
104-
Schema.Table.name= "VM"
105-
; columns=
106-
[_ref; uuid; name_label; vbds; pp; name_description; tags; other_config]
107-
; persistent= true
108-
}
102+
let vm_table : Schema.Table.t =
103+
Schema.Table.t_of_t'
104+
{
105+
Schema.Table.name= "VM"
106+
; columns=
107+
[
108+
_ref
109+
; uuid
110+
; name_label
111+
; vbds
112+
; pp
113+
; name_description
114+
; tags
115+
; other_config
116+
]
117+
; persistent= true
118+
}
109119
in
110120
let vbd_table =
111-
{
112-
Schema.Table.name= "VBD"
113-
; columns= [_ref; uuid; vm; type']
114-
; persistent= true
115-
}
121+
Schema.Table.t_of_t'
122+
{
123+
Schema.Table.name= "VBD"
124+
; columns= [_ref; uuid; vm; type']
125+
; persistent= true
126+
}
127+
in
128+
let database =
129+
Schema.Database.t_of_t' {Schema.Database.tables= [vm_table; vbd_table]}
116130
in
117-
let database = {Schema.Database.tables= [vm_table; vbd_table]} in
118131
let one_to_many =
119132
Schema.ForeignMap.add "VBD" [("VM", "VM", "VBDs")] Schema.ForeignMap.empty
120133
in
@@ -140,12 +153,16 @@ let many_to_many =
140153
in
141154
let foo_column = {bar_column with Schema.Column.name= "foos"} in
142155
let foo_table =
143-
{Schema.Table.name= "foo"; columns= [bar_column]; persistent= true}
156+
Schema.Table.t_of_t'
157+
{Schema.Table.name= "foo"; columns= [bar_column]; persistent= true}
144158
in
145159
let bar_table =
146-
{Schema.Table.name= "bar"; columns= [foo_column]; persistent= true}
160+
Schema.Table.t_of_t'
161+
{Schema.Table.name= "bar"; columns= [foo_column]; persistent= true}
162+
in
163+
let database =
164+
Schema.Database.t_of_t' {Schema.Database.tables= [foo_table; bar_table]}
147165
in
148-
let database = {Schema.Database.tables= [foo_table; bar_table]} in
149166
let many_to_many =
150167
Schema.ForeignMap.add "foo"
151168
[("bars", "bar", "foos")]

ocaml/idl/datamodel_lifecycle.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ let prototyped_of_field = function
5252
| "VTPM", "persistence_backend" ->
5353
Some "22.26.0"
5454
| "SM", "host_pending_features" ->
55-
Some "24.36.0-next"
55+
Some "24.37.0"
5656
| "host", "last_update_hash" ->
5757
Some "24.10.0"
5858
| "host", "pending_guidances_full" ->

ocaml/idl/datamodel_schema.ml

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -85,14 +85,16 @@ let of_datamodel () =
8585
in
8686

8787
let table obj =
88-
{
89-
Table.name= Escaping.escape_obj obj.Datamodel_types.name
90-
; columns=
91-
_ref
92-
:: List.map (column obj) (flatten_fields obj.Datamodel_types.contents [])
93-
; persistent=
94-
obj.Datamodel_types.persist = Datamodel_types.PersistEverything
95-
}
88+
Table.t_of_t'
89+
{
90+
Table.name= Escaping.escape_obj obj.Datamodel_types.name
91+
; columns=
92+
_ref
93+
:: List.map (column obj)
94+
(flatten_fields obj.Datamodel_types.contents [])
95+
; persistent=
96+
obj.Datamodel_types.persist = Datamodel_types.PersistEverything
97+
}
9698
in
9799
let is_one_to_many x =
98100
match Datamodel_utils.Relations.classify Datamodel.all_api x with
@@ -119,7 +121,8 @@ let of_datamodel () =
119121
in
120122

121123
let database api =
122-
{Database.tables= List.map table (Dm_api.objects_of_api api)}
124+
let tables = List.map table (Dm_api.objects_of_api api) in
125+
Database.of_tables tables
123126
in
124127
{
125128
major_vsn= Datamodel_common.schema_major_vsn

ocaml/idl/ocaml_backend/gen_api.ml

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -241,8 +241,8 @@ let gen_record_type ~with_module highapi tys =
241241
[
242242
sprintf "let rpc_of_%s_t x = Rpc.Dict (unbox_list [ %s ])"
243243
obj_name (map_fields make_of_field)
244-
; sprintf "let %s_t_of_rpc x = on_dict (fun x -> { %s }) x" obj_name
245-
(map_fields make_to_field)
244+
; sprintf "let %s_t_of_rpc x = on_dict (fun x assocer -> { %s }) x"
245+
obj_name (map_fields make_to_field)
246246
; sprintf
247247
"type ref_%s_to_%s_t_map = (ref_%s * %s_t) list [@@deriving \
248248
rpc]"
@@ -408,10 +408,6 @@ let gen_client_types highapi =
408408
x | _ -> failwith \"Date.t_of_rpc\""
409409
; "end"
410410
]
411-
; [
412-
"let on_dict f = function | Rpc.Dict x -> f x | _ -> failwith \
413-
\"Expected Dictionary\""
414-
]
415411
; ["let opt_map f = function | None -> None | Some x -> Some (f x)"]
416412
; [
417413
"let unbox_list = let rec loop aux = function"
@@ -421,14 +417,21 @@ let gen_client_types highapi =
421417
; "loop []"
422418
]
423419
; [
424-
"let assocer key map default = "
425-
; " try"
426-
; " List.assoc key map"
427-
; " with Not_found ->"
428-
; " match default with"
429-
; " | Some d -> d"
430-
; " | None -> failwith (Printf.sprintf \"Field %s not present in \
431-
rpc\" key)"
420+
"let assocer kvs ="
421+
; "let tbl = Hashtbl.create 256 in"
422+
; "List.iter (fun (k, v) -> Hashtbl.replace tbl k v) kvs;"
423+
; "fun key _ default ->"
424+
; "match Hashtbl.find_opt tbl key with"
425+
; "| Some v -> v"
426+
; "| _ ->"
427+
; " match default with"
428+
; " | Some d -> d"
429+
; " | _ -> failwith (Printf.sprintf \"Field %s not present in rpc\" \
430+
key)"
431+
]
432+
; [
433+
"let on_dict f = function | Rpc.Dict x -> f x (assocer x) | _ -> \
434+
failwith \"Expected Dictionary\""
432435
]
433436
; gen_non_record_type all_types
434437
; gen_record_type ~with_module:true highapi

0 commit comments

Comments
 (0)