diff options
| author | Marcos Magueta <maguetamarcos@gmail.com> | 2026-03-07 02:40:26 -0300 |
|---|---|---|
| committer | Marcos Magueta <maguetamarcos@gmail.com> | 2026-03-07 02:40:26 -0300 |
| commit | e9bc4aa3fa0e775acf1978722da1fde1ed8a469d (patch) | |
| tree | ff78d21ba9a03acae20b15bb2fad2f27bcde75e1 /lib/management/database.ml | |
| parent | fcd8571577f2b98ffc8fa2b95781ed16982804a9 (diff) | |
| download | Sakura-e9bc4aa3fa0e775acf1978722da1fde1ed8a469d.tar.gz Sakura-e9bc4aa3fa0e775acf1978722da1fde1ed8a469d.zip | |
erlang port commands and generated tests
Diffstat (limited to '')
| -rw-r--r-- | lib/management/database.ml | 104 |
1 files changed, 89 insertions, 15 deletions
diff --git a/lib/management/database.ml b/lib/management/database.ml index 4fd43f1..1e68402 100644 --- a/lib/management/database.ml +++ b/lib/management/database.ml @@ -1,23 +1,97 @@ -module RelationMap = Map.Make (String) +(** Database state management. + + A database is a collection of relations with: + - A merkle tree of relation hashes (for integrity verification) + - A map of relation names to their actual Relation.t objects (integrated cache) + - A history of previous database hashes (for time-travel queries) + + All mutations produce a new database state with a new hash. + The history chain allows reconstruction of any past state. *) + +module RelationMap = Map.Make(String) type t = { hash : Conventions.Hash.t; name : Conventions.Name.t; - tree : unit; - relations : Relation.t RelationMap.t; + tree : Merkle.t; + relations : Relation.t RelationMap.t; (* Stores actual relations, not just hashes *) + history : Conventions.Hash.t list; timestamp : float; } -let create_database (storage: Physical.Storage.t) ~name = - let relations = - RelationMap.of_list [("less_than", Prelude.Standard.less_than_natural)] +let empty ~name = { + hash = ""; + name; + tree = Merkle.empty; + relations = RelationMap.empty; + history = []; + timestamp = Unix.gettimeofday (); +} + +(** Compute database hash from the merkle tree root *) +let compute_hash db = + match Merkle.root_hash db.tree with + | Some root -> root + | None -> Conventions.Hash.hash_text db.name + +(** Update database with new relations map and tree *) +let update_state db ~relations ~tree = + let new_hash = + match Merkle.root_hash tree with + | Some root -> root + | None -> Conventions.Hash.hash_text db.name in - let state = - { - hash = ""; - name; - tree = (); - relations = relations; - timestamp = Unix.time (); - } - in Physical.Storage.write storage + let history = if db.hash = "" then db.history else db.hash :: db.history in + { + hash = new_hash; + name = db.name; + tree; + relations; + history; + timestamp = Unix.gettimeofday (); + } + +(** Get a relation by name *) +let get_relation db name = + RelationMap.find_opt name db.relations + +(** Get a relation's hash by name *) +let get_relation_hash db name = + match RelationMap.find_opt name db.relations with + | None -> None + | Some rel -> rel.Relation.hash + +let get_relation_names db = + RelationMap.fold (fun name _ acc -> name :: acc) db.relations [] + +let has_relation db name = + RelationMap.mem name db.relations + +(** Add a relation to the database *) +let add_relation db ~(relation : Relation.t) = + let relation_hash = Option.get relation.hash in + let tree = Merkle.insert relation_hash db.tree in + let relations = RelationMap.add relation.name relation db.relations in + update_state db ~relations ~tree + +(** Remove a relation from the database *) +let remove_relation db ~name = + match RelationMap.find_opt name db.relations with + | None -> db + | Some relation -> + let relation_hash = Option.get relation.hash in + let tree = Merkle.delete relation_hash db.tree in + let relations = RelationMap.remove name db.relations in + update_state db ~relations ~tree + +(** Update a relation in the database (after tuple insert/delete) *) +let update_relation db ~(relation : Relation.t) = + let name = relation.name in + match RelationMap.find_opt name db.relations with + | None -> db (* Relation doesn't exist, no-op *) + | Some old_relation -> + let old_hash = Option.get old_relation.hash in + let new_hash = Option.get relation.hash in + let tree = db.tree |> Merkle.delete old_hash |> Merkle.insert new_hash in + let relations = RelationMap.add name relation db.relations in + update_state db ~relations ~tree |
