| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- /**
- * ChildrenStorage - Low-level storage for structural children
- *
- * Handles the 'children:' prefix for storing container child names.
- *
- * Key format: children:<parent_path>
- * Value: Serialized array of child names
- *
- * @version 0.1
- * @since 0.1
- */
- namespace Implexus.Storage.LowLevel {
- /**
- * Low-level storage for structural children.
- *
- * This class provides type-safe operations for storing and retrieving
- * structural child names using the 'children:' key prefix.
- */
- public class ChildrenStorage : Object {
-
- /**
- * Key prefix for children entries.
- */
- private const string PREFIX = "children:";
-
- /**
- * The underlying Dbm storage.
- */
- private Dbm _dbm;
-
- /**
- * Creates a new ChildrenStorage with the given Dbm backend.
- *
- * @param dbm The Dbm backend to use for storage
- */
- public ChildrenStorage(Dbm dbm) {
- _dbm = dbm;
- }
-
- /**
- * Adds a child name to a parent's children set.
- *
- * @param parent The parent entity path
- * @param child_name The name of the child to add
- * @throws StorageError if the operation fails
- */
- public void add_child(Core.EntityPath parent, string child_name) throws StorageError {
- var children = load_children_set(parent);
- if (!children.contains(child_name)) {
- children.add(child_name);
- save_children_set(parent, children);
- }
- }
-
- /**
- * Removes a child name from a parent's children set.
- *
- * @param parent The parent entity path
- * @param child_name The name of the child to remove
- * @throws StorageError if the operation fails
- */
- public void remove_child(Core.EntityPath parent, string child_name) throws StorageError {
- var children = load_children_set(parent);
- if (children.contains(child_name)) {
- children.remove(child_name);
- save_children_set(parent, children);
- }
- }
-
- /**
- * Checks if a parent has a specific child.
- *
- * @param parent The parent entity path
- * @param child_name The name of the child to check
- * @return True if the child exists
- */
- public bool has_child(Core.EntityPath parent, string child_name) {
- var children = load_children_set(parent);
- return children.contains(child_name);
- }
-
- /**
- * Gets all child names for a parent.
- *
- * @param parent The parent entity path
- * @return An enumerable of child names
- */
- public Invercargill.Enumerable<string> get_children(Core.EntityPath parent) {
- var children = load_children_set(parent);
- return children.as_enumerable();
- }
-
- /**
- * Deletes all children for a parent.
- *
- * @param parent The parent entity path
- * @throws StorageError if the operation fails
- */
- public void delete(Core.EntityPath parent) throws StorageError {
- string key = PREFIX + parent.to_string();
- try {
- _dbm.delete(key);
- } catch (StorageError e) {
- // Key doesn't exist, that's fine
- }
- }
-
- /**
- * Loads the children set for a parent.
- *
- * @param parent The parent entity path
- * @return A vector of child names (empty if not found)
- */
- private Invercargill.DataStructures.Vector<string> load_children_set(Core.EntityPath parent) {
- string key = PREFIX + parent.to_string();
- var result = new Invercargill.DataStructures.Vector<string>();
- var data = _dbm.get(key);
-
- if (data == null) {
- return result;
- }
-
- var reader = new ElementReader((!) data);
- try {
- var element = reader.read_element();
- if (element.is_null()) {
- return result;
- }
-
- // The children set is stored as an array of strings
- var array = element.as<Invercargill.Enumerable<Invercargill.Element>>();
- foreach (var child_element in array) {
- if (!child_element.is_null()) {
- string child_name = child_element.as<string>();
- if (!result.contains(child_name)) {
- result.add(child_name);
- }
- }
- }
- } catch (Invercargill.ElementError e) {
- warning("Failed to read children set: %s", e.message);
- }
-
- return result;
- }
-
- /**
- * Saves the children set for a parent.
- *
- * @param parent The parent entity path
- * @param children The set of child names to save
- * @throws StorageError if the operation fails
- */
- private void save_children_set(Core.EntityPath parent, Invercargill.DataStructures.Vector<string> children) throws StorageError {
- string key = PREFIX + parent.to_string();
-
- uint count = children.count();
- if (count == 0) {
- try {
- _dbm.delete(key);
- } catch (StorageError e) {
- // Key doesn't exist, that's fine
- }
- return;
- }
-
- // Store as array of strings
- var array = new Invercargill.DataStructures.Vector<Invercargill.Element>();
- foreach (var child_name in children) {
- var element = new Invercargill.NativeElement<string>(child_name);
- array.add(element);
- }
-
- var writer = new ElementWriter();
- writer.write_element(new Invercargill.NativeElement<Invercargill.Enumerable<Invercargill.Element>>(array));
- _dbm.set(key, writer.to_binary_data());
- }
- }
- } // namespace Implexus.Storage.LowLevel
|