Repodb.Multi
repodb · API reference
Transactional composition of named database operations.
A multi is an ordered set of named operations executed inside one transaction. Each operation can read results produced by earlier operations, which makes it useful for workflows such as "insert a user, then insert an audit event with that user id".
let create_user_and_log email =
Multi.empty
|> Multi.insert_returning "user" ~table:User.table ~columns:[ "email" ]
~values:[ Driver.Value.text email ]
|> Multi.insert_fn "audit" (fun results ->
let row = Multi.get_row_raw_exn results "user" in
let user_id = Driver.row_int64 row "id" in
( Audit.table,
[ "user_id"; "event" ],
[ Driver.Value.int64 user_id; Driver.Value.text "created" ] ))Make(D).execute conn multi returns either all named results or a multi_error containing the failing operation name, normalized database error, and results completed before the failure. The surrounding transaction is rolled back on failure, so completed is diagnostic information, not a list of committed writes.
Use validate_multi in tests or CLIs to catch duplicate operation names before execution. Prefer descriptive names because they are the keys used to retrieve results and the names reported in errors.
module StringMap : sig ... endtype stored_result =
| Unit
| Row of Driver.row
| Rows of Driver.row listtype results = stored_result StringMap.ttype multi_error = {
failed_operation : string;
error : Error.db_error;
completed : results;
}val empty_results : 'a StringMap.tval get_unit : stored_result StringMap.t -> StringMap.key -> unit optionval get_unit_exn : stored_result StringMap.t -> StringMap.key -> unitval get_row :
stored_result StringMap.t ->
StringMap.key ->
decode:(Driver.row -> 'a) ->
'a optionval get_row_exn :
stored_result StringMap.t ->
StringMap.key ->
decode:(Driver.row -> 'a) ->
'aval get_row_raw :
stored_result StringMap.t ->
StringMap.key ->
Driver.row optionval get_row_raw_exn : stored_result StringMap.t -> StringMap.key -> Driver.rowval get_rows :
stored_result StringMap.t ->
StringMap.key ->
decode:(Driver.row -> 'a) ->
'a list optionval get_rows_exn :
stored_result StringMap.t ->
StringMap.key ->
decode:(Driver.row -> 'a) ->
'a listval get_rows_raw :
stored_result StringMap.t ->
StringMap.key ->
Driver.row list optionval get_rows_raw_exn :
stored_result StringMap.t ->
StringMap.key ->
Driver.row listval put_unit : StringMap.key -> stored_result StringMap.t -> resultsval put_row :
StringMap.key ->
Driver.row ->
stored_result StringMap.t ->
resultsval put_rows :
StringMap.key ->
Driver.row list ->
stored_result StringMap.t ->
resultstype 'conn operation =
| Insert of {
table : Schema.table;
columns : string list;
values : Driver.Value.t list;
}
| InsertFn of {
f : results -> Schema.table * string list * Driver.Value.t list;
}
| InsertReturning of {
table : Schema.table;
columns : string list;
values : Driver.Value.t list;
}
| InsertReturningFn of {
f : results -> Schema.table * string list * Driver.Value.t list;
}
| Update of {
table : Schema.table;
columns : string list;
values : Driver.Value.t list;
where_column : string;
where_value : Driver.Value.t;
}
| UpdateFn of {
f : results ->
Schema.table * string list * Driver.Value.t list * string * Driver.Value.t;
}
| Delete of {
table : Schema.table;
where_column : string;
where_value : Driver.Value.t;
}
| DeleteFn of {
f : results -> Schema.table * string * Driver.Value.t;
}
| Run of {
f : 'conn -> results -> (stored_result, Error.db_error) result;
}type 'conn entry = {
name : string;
op : 'conn operation;
}type 'conn t = 'conn entry listval new_multi : unit -> 'conn tval empty : 'conn tval insert :
string ->
table:Schema.table ->
columns:string list ->
values:Driver.Value.t list ->
'conn t ->
'conn tval insert_fn :
string ->
f:(results -> Schema.table * string list * Driver.Value.t list) ->
'conn t ->
'conn tval insert_returning :
string ->
table:Schema.table ->
columns:string list ->
values:Driver.Value.t list ->
'conn t ->
'conn tval insert_returning_fn :
string ->
f:(results -> Schema.table * string list * Driver.Value.t list) ->
'conn t ->
'conn tval update :
string ->
table:Schema.table ->
columns:string list ->
values:Driver.Value.t list ->
where_column:string ->
where_value:Driver.Value.t ->
'conn t ->
'conn tval update_fn :
string ->
f:
(results ->
Schema.table
* string list
* Driver.Value.t list
* string
* Driver.Value.t) ->
'conn t ->
'conn tval delete :
string ->
table:Schema.table ->
where_column:string ->
where_value:Driver.Value.t ->
'conn t ->
'conn tval delete_fn :
string ->
f:(results -> Schema.table * string * Driver.Value.t) ->
'conn t ->
'conn tval run :
string ->
f:('conn -> results -> (stored_result, Error.db_error) result) ->
'conn t ->
'conn tval run_no_result :
string ->
f:('conn -> results -> (unit, Error.db_error) result) ->
'conn t ->
'conn tval run_unit :
string ->
f:('conn -> results -> (unit, Error.db_error) result) ->
'conn t ->
'conn tval run_row :
string ->
f:('conn -> results -> (Driver.row, Error.db_error) result) ->
'conn t ->
'conn tval run_rows :
string ->
f:('conn -> results -> (Driver.row list, Error.db_error) result) ->
'conn t ->
'conn tval merge : 'conn t -> 'conn t -> 'conn tval to_list : 'conn t -> 'conn tval names : 'conn t -> string listval has_name : string -> 'conn t -> boolval validate_multi : 'conn t -> (unit, string) resultmodule Make (D : Driver.S) : sig ... end