Files
DotNetAlpm/Alpm/Database.cs
2020-04-30 17:27:50 -04:00

121 lines
3.8 KiB
C#

using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace Foodsoft.Alpm
{
public sealed class Database : IDisposable
{
[Flags]
public enum UsageFlags
{
Sync = 1,
Search = (1 << 1),
Install = (1 << 2),
Upgrade = (1 << 3),
All = (1 << 4) - 1,
}
private readonly SafeDatabaseHandle _handle;
internal Database(SafeDatabaseHandle handle) => _handle = handle;
public void Unregister() => _handle.Close();
public void AddServer(string url) =>
Detail.WrapError(_handle.SafeAlpmHandle, () => alpm.alpm_db_add_server(_handle, url));
public bool RemoveServer(string url) =>
Detail.WrapErrorBool(_handle.SafeAlpmHandle, () => alpm.alpm_db_remove_server(_handle, url));
// FIXME: This is "bug correct", but probably dumb to do it this way, instead just call add_server
// like all the stuff in handle.
public IEnumerable<string> Servers
{
get => EnumerableWrapper.Create(_handle, alpm.alpm_db_get_servers);
set
{
var listPtr = IntPtr.Zero;
var success = false;
var err = 0;
RuntimeHelpers.PrepareConstrainedRegions();
try
{
// ReSharper disable once LoopCanBeConvertedToQuery
foreach (var s in value)
{
if (alpm.alpm_list_append_strdup(ref listPtr, s) == IntPtr.Zero)
throw new AlpmException(ErrNo.ERR_MEMORY);
}
success = true;
}
finally
{
if (success)
err = alpm.alpm_db_set_servers(_handle, listPtr);
else
alpm.alpm_list_free(listPtr);
}
if (err != 0)
throw new AlpmException(_handle.SafeAlpmHandle);
}
}
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 AlpmException(_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 AlpmException(err);
}
return new CachePackage(new SafeCachePackageHandle(pkgPtr, _handle), this);
}
public CachePackageList PackageCache
{
get
{
var listPtr = alpm.alpm_db_get_pkgcache(_handle);
if (listPtr == IntPtr.Zero)
throw new AlpmException(_handle.SafeAlpmHandle);
return new CachePackageList(listPtr, _handle, this);
}
}
public CachePackageList Search()
{
}
public UsageFlags Usage => Detail.WrapError<UsageFlags, SafeDatabaseHandle>(_handle.SafeAlpmHandle, _handle, alpm.alpm_db_get_usage);
public void Dispose()
{
_handle.Dispose();
}
}
}