144 lines
4.5 KiB
C#
144 lines
4.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Runtime.ConstrainedExecution;
|
|
|
|
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;
|
|
}
|
|
|
|
// FIXME: This is "bug correct", but probably dumb to do it this way, instead just call add_server
|
|
// like all the stuff in handle.
|
|
// Also this stupid thing leaks the duped strings on failure.
|
|
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(Error.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 Error Valid =>
|
|
alpm.alpm_db_get_valid(_handle) != 0 ? alpm.alpm_errno(_handle.SafeAlpmHandle) : Error.OK;
|
|
|
|
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 UsageFlags Usage
|
|
{
|
|
get => Detail.WrapErrorOut<SafeDatabaseHandle, UsageFlags>(_handle.SafeAlpmHandle, _handle,
|
|
alpm.alpm_db_get_usage);
|
|
set => Detail.WrapErrorIn(_handle.SafeAlpmHandle, _handle, value, alpm.alpm_db_set_usage);
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
_handle.Dispose();
|
|
}
|
|
|
|
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)
|
|
{
|
|
return Detail.WrapErrorBool(_handle.SafeAlpmHandle, () => alpm.alpm_db_remove_server(_handle, url));
|
|
}
|
|
|
|
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 == Error.PkgNotFound)
|
|
return null;
|
|
throw new AlpmException(err);
|
|
}
|
|
|
|
return new CachePackage(new SafeCachePackageHandle(pkgPtr, _handle), this);
|
|
}
|
|
|
|
[PrePrepareMethod]
|
|
[SuppressMessage("ReSharper", "LoopCanBeConvertedToQuery")]
|
|
public CachePackageList Search(IEnumerable<string> needles)
|
|
{
|
|
var result = Detail.UseStringList(needles, listPtr => alpm.alpm_db_search(_handle, listPtr));
|
|
if (result == IntPtr.Zero)
|
|
{
|
|
var errNo = alpm.alpm_errno(_handle.SafeAlpmHandle);
|
|
if (errNo != Error.OK)
|
|
throw new AlpmException(errNo);
|
|
}
|
|
|
|
return new CachePackageList(result, _handle, this);
|
|
}
|
|
}
|
|
} |