using System; using System.Collections.Generic; using System.Runtime.InteropServices; namespace Foodsoft.Alpm { public sealed class Database : IDisposable { private readonly SafeDatabaseHandle _handle; internal Database(SafeDatabaseHandle handle) => _handle = handle; public void Unregister() { try { API.WrapError(_handle.SafeAlpmHandle, () => alpm.alpm_db_unregister(_handle)); } finally { _handle.Close(); } } private readonly struct ServersAccessor : IItemsReader { internal ServersAccessor(SafeDatabaseHandle handle) { Handle = handle; } public SafeDatabaseHandle Handle { get; } public IntPtr GetItems() => alpm.alpm_db_get_servers(Handle); public string PtrToItem(IntPtr p) => Marshal.PtrToStringUTF8(p)!; } public void AddServer(string url) => API.WrapError(_handle.SafeAlpmHandle, () => alpm.alpm_db_add_server(_handle, url)); public bool RemoveServer(string url) => API.WrapErrorBool(_handle.SafeAlpmHandle, () => alpm.alpm_db_remove_server(_handle, url)); public IEnumerable Servers { get => new EnumerableWrapper(new ServersAccessor(_handle)); set { foreach (var s in value) { API.WrapError(_handle.SafeAlpmHandle, () => alpm.alpm_db_add_server(_handle, s)); } } } public string Name => alpm.alpm_db_get_name(_handle); public SigLevel SigLevel => alpm.alpm_db_get_siglevel(_handle); public ErrNo Valid => alpm.alpm_db_get_valid(_handle) != 0 ? alpm.alpm_errno(_handle.SafeAlpmHandle) : ErrNo.ERR_OK; public bool Update(bool force = false) { var err = alpm.alpm_db_update(force ? 1 : 0, _handle); if (err < 0) { throw new Exception(_handle.SafeAlpmHandle); } return err == 0; } public Package? GetPackage(string name) { var pkgPtr = alpm.alpm_pkg_get_pkg(_handle, name); if (pkgPtr == IntPtr.Zero) { var err = alpm.alpm_errno(_handle.SafeAlpmHandle); if (err == ErrNo.ERR_PKG_NOT_FOUND) return null; throw new Exception(err); } return new CachePackage(new SafeCachePackageHandle(pkgPtr, _handle), this); } public PackageList PackageCache { get { var listPtr = alpm.alpm_db_get_pkgcache(_handle); if (listPtr == IntPtr.Zero) throw new Exception(alpm.alpm_errno(_handle.SafeAlpmHandle)); return new PackageList(new SafeListHandle(listPtr, _handle), this); } } public void Dispose() { _handle.Dispose(); } } }