using DeepDrftContent.FileDatabase.Models; using DeepDrftContent.FileDatabase.Utils; namespace DeepDrftContent.FileDatabase.Services; /// /// Main file database class that orchestrates multiple media vaults /// public class FileDatabase : DirectoryIndexDirectory { private readonly StructuralMap _vaults; /// /// Factory method to create a FileDatabase instance /// public static async Task FromAsync(string rootPath) { var factory = new IndexFactory(rootPath, IndexType.Directory); var rootIndex = await factory.BuildIndexAsync(); if (rootIndex is DirectoryIndex directoryIndex) { var db = new FileDatabase(rootPath, directoryIndex); await db.InitVaultsAsync(); return db; } return null; } private FileDatabase(string rootPath, DirectoryIndex index) : base(rootPath, index) { _vaults = new StructuralMap(); } /// /// Initializes all vaults found in the index /// private async Task InitVaultsAsync() { foreach (var vaultKey in GetIndexEntries()) { await InitVaultAsync(vaultKey); } } /// /// Initializes a specific vault /// private async Task InitVaultAsync(EntryKey vaultKey) { var path = Path.Combine(RootPath, vaultKey.Key); var directoryVault = await MediaVaultFactory.From(path, vaultKey.Type); if (directoryVault != null) { _vaults.Set(vaultKey, directoryVault); } } /// /// Checks if a vault exists for the given key /// public bool HasVault(EntryKey vaultKey) { return _vaults.Has(vaultKey); } /// /// Gets a vault by key /// public MediaVault? GetVault(EntryKey vaultKey) { return HasVault(vaultKey) ? _vaults.Get(vaultKey) : null; } /// /// Creates a new vault /// public async Task CreateVaultAsync(EntryKey vaultKey) { try { var path = Path.Combine(RootPath, vaultKey.Key); var directoryVault = await MediaVaultFactory.From(path, vaultKey.Type); if (directoryVault != null) { _vaults.Set(vaultKey, directoryVault); await AddToIndexAsync(vaultKey); } } catch { throw; } } /// /// Loads a resource from a specific vault /// public async Task LoadResourceAsync(MediaVaultType vaultType, EntryKey vaultKey, EntryKey entryKey) where T : FileBinary { try { var vault = _vaults.Get(vaultKey); if (vault != null) { return await vault.GetEntryAsync(vaultType, entryKey); } } catch { // Swallow exceptions and return null, matching TypeScript behavior } return null; } /// /// Registers a resource in a specific vault /// public async Task RegisterResourceAsync(MediaVaultType vaultType, EntryKey vaultKey, EntryKey entryKey, object media) { try { var directoryVault = _vaults.Get(vaultKey); if (directoryVault != null) { await directoryVault.AddEntryAsync(vaultType, entryKey, media); return true; } } catch { // Swallow exceptions and return false, matching TypeScript behavior } return false; } /// /// Gets all vault keys managed by this database /// public IReadOnlyList GetVaultKeys() { return _vaults.Keys.ToList().AsReadOnly(); } /// /// Gets the total number of vaults /// public int GetVaultCount() { return _vaults.Size; } }