Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file ocsipersist_lib.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317(** This modules provides tools for creating more implementations of the {!Ocsipersist} virtual module. *)moduleSigs=structmoduletypeTABLE=sigtypekeytypevaluevalname:stringvalfind:key->valueLwt.tvaladd:key->value->unitLwt.tvalreplace_if_exists:key->value->unitLwt.tvalremove:key->unitLwt.tvalmodify_opt:key->(valueoption->valueoption)->unitLwt.tvallength:unit->intLwt.tvaliter:?count:int64->?gt:key->?geq:key->?lt:key->?leq:key->(key->value->unitLwt.t)->unitLwt.tvalfold:?count:int64->?gt:key->?geq:key->?lt:key->?leq:key->(key->value->'a->'aLwt.t)->'a->'aLwt.tvaliter_block:?count:int64->?gt:key->?geq:key->?lt:key->?leq:key->(key->value->unit)->unitLwt.tvaliter_batch:?count:int64->?gt:key->?geq:key->?lt:key->?leq:key->((key*value)list->unitLwt.t)->unitLwt.tmoduleVariable:sigtypetvalmake:name:key->default:value->tvalmake_lazy:name:key->default:(unit->value)->tvalmake_lazy_lwt:name:key->default:(unit->valueLwt.t)->tvalget:t->valueLwt.tvalset:t->value->unitLwt.tendendmoduletypeFUNCTORIAL=sigtypeinternalmoduletypeCOLUMN=sigtypetvalcolumn_type:stringvalencode:t->internalvaldecode:internal->tendmoduleTable(T:sigvalname:stringend)(Key:COLUMN)(Value:COLUMN):TABLEwithtypekey=Key.tandtypevalue=Value.tmoduleColumn:sigmoduleString:COLUMNwithtypet=stringmoduleFloat:COLUMNwithtypet=floatmoduleMarshal(C:sigtypetend):COLUMNwithtypet=C.tendendmoduletypePOLYMORPHIC=sigtype'valuetable(** Type of persistent table *)valtable_name:'valuetable->stringLwt.t(** returns the name of the table *)valopen_table:string->'valuetableLwt.t(** Open a table (and create it if it does not exist) *)valfind:'valuetable->string->'valueLwt.t(** [find table key] gives the value associated to [key].
Fails with [Not_found] if not found. *)valadd:'valuetable->string->'value->unitLwt.t(** [add table key value] associates [value] to [key].
If the database already contains data associated with [key],
that data is discarded and silently replaced by the new data.
*)valreplace_if_exists:'valuetable->string->'value->unitLwt.t(** [replace_if_exists table key value]
associates [value] to [key] only if [key] is already bound.
If the database does not contain any data associated with [key],
fails with [Not_found].
*)valremove:'valuetable->string->unitLwt.t(** [remove table key] removes the entry in the table if it exists *)vallength:'valuetable->intLwt.t(** Size of a table. *)valiter_step:(string->'a->unitLwt.t)->'atable->unitLwt.t(** Important warning: this iterator may not iter on all data of the table
if another thread is modifying it in the same time. Nonetheless, it should
not miss more than a very few data from time to time, except if the table
is very old (at least 9 223 372 036 854 775 807 insertions).
*)valfold_step:(string->'a->'b->'bLwt.t)->'atable->'b->'bLwt.t(** Important warning: this iterator may not iter on all data of the table
if another thread is modifying it in the same time. Nonetheless, it should
not miss more than a very few data from time to time, except if the table
is very old (at least 9 223 372 036 854 775 807 insertions).
*)valiter_block:(string->'a->unit)->'atable->unitLwt.t(** MAJOR WARNING: Unlike iter_step, this iterator won't miss any
entry and will run in one shot. It is therefore more efficient, BUT:
it will lock the WHOLE database during its execution,
thus preventing ANYBODY from accessing it (including the function f
which is iterated).
As a consequence: you MUST NOT use any function from ocsipersist in f,
otherwise you would lock yourself and everybody else! Be VERY cautious.
*)endmoduletypeREF=sig(** Persistent references for OCaml *)type'at(** The type of (persistent or not) references *)valref:?persistent:string->'a->'at(** [ref ?persistent default] creates a reference.
If optional parameter [?persistent] is absent,
+ the reference will not be persistent (implemented using OCaml references).
+ Otherwise, the value of [persistent] will be used as key for the
+ value in the persistent reference table.
If the reference already exists, the current value is kept.
+ Be careful to change this name every time you change the type of the
+ value. *)valget:'at->'aLwt.t(** Get the value of a reference *)valset:'at->'a->unitLwt.t(** Set the value of a reference *)endmoduletypeSTORE=sigtype'at(** Type of persistent data *)typestore(** Data are divided into stores.
Create one store for your project, where you will save all your data. *)valopen_store:string->storeLwt.t(** Open a store (and create it if it does not exist) *)valmake_persistent:store:store->name:string->default:'a->'atLwt.t(** [make_persistent store name default] find a persistent value
named [name] in store [store]
from database, or create it with the default value [default] if it
does not exist. *)valmake_persistent_lazy:store:store->name:string->default:(unit->'a)->'atLwt.t(** Same as make_persistent but the default value is evaluated only
if needed
*)valmake_persistent_lazy_lwt:store:store->name:string->default:(unit->'aLwt.t)->'atLwt.t(** Lwt version of make_persistent_lazy.
*)valget:'at->'aLwt.t(** [get pv] gives the value of [pv] *)valset:'at->'a->unitLwt.t(** [set pv value] sets a persistent value [pv] to [value] *)endendopenSigsopenLwt.Infix(** deriving polymorphic interface from the functorial one *)modulePolymorphic(Functorial:FUNCTORIAL):POLYMORPHIC=structmoduletypePOLYMORPHIC=TABLEwithtypekey=stringtype'valuetable=(modulePOLYMORPHICwithtypevalue='value)letopen_table(typea)name=letopenFunctorialinletmoduleT=Table(structletname=nameend)(Column.String)(Column.Marshal(structtypet=aend))inLwt.return(moduleT:POLYMORPHICwithtypevalue=a)lettable_name(typea)(moduleT:POLYMORPHICwithtypevalue=a)=Lwt.returnT.nameletfind(typea)(moduleT:POLYMORPHICwithtypevalue=a)=T.findletadd(typea)(moduleT:POLYMORPHICwithtypevalue=a)=T.addletreplace_if_exists(typea)(moduleT:POLYMORPHICwithtypevalue=a)=T.replace_if_existsletremove(typea)(moduleT:POLYMORPHICwithtypevalue=a)=T.removeletlength(typea)(moduleT:POLYMORPHICwithtypevalue=a)=T.length()letiter_step(typea)f(moduleT:POLYMORPHICwithtypevalue=a)=T.iterfletfold_step(typea)f(moduleT:POLYMORPHICwithtypevalue=a)=T.foldfletiter_block(typea)f(moduleT:POLYMORPHICwithtypevalue=a)=T.iter_blockfendmoduleVariable(T:sigtypektypevvalfind:k->vLwt.tvaladd:k->v->unitLwt.tend)=structtypet={name:T.k;default:unit->T.vLwt.t}letmake_lazy_lwt~name~default={name;default}letmake_lazy~name~default={name;default=(fun()->Lwt.return@@default())}letmake~name~default={name;default=(fun()->Lwt.returndefault)}letget{name;default}=try%lwtT.findnamewithNot_found->default()>>=fund->T.addnamed>>=fun()->Lwt.returndletset{name}=T.addnameendmoduleRef(Store:STORE)=structletstore=lazy(Store.open_store"__ocsipersist_ref_store__")type'at=Refof'aref|Perof'aStore.tLwt.tletref?persistentv=matchpersistentwith|None->Ref(refv)|Somename->Per(let%lwtstore=Lazy.forcestoreinStore.make_persistent~store~name~default:v)letget=function|Refr->Lwt.return!r|Perr->let%lwtr=rinStore.getrletsetrv=matchrwith|Refr->r:=v;Lwt.return_unit|Perr->let%lwtr=rinStore.setrvend