242 lines
13 KiB
C#
242 lines
13 KiB
C#
namespace Explorer.Domain.Abstractions;
|
|
|
|
public interface IIndexStore
|
|
{
|
|
Task OpenAsync(CancellationToken cancellationToken = default);
|
|
Task CloseAsync();
|
|
Task<string> QuickCheckAsync(CancellationToken cancellationToken = default);
|
|
|
|
ISourceStore Sources { get; }
|
|
IEntryStore Entries { get; }
|
|
IExcludeStore Excludes { get; }
|
|
IScanJobStore ScanJobs { get; }
|
|
ITransferStore Transfers { get; }
|
|
ISearchStore Search { get; }
|
|
IAnalysisStore Analysis { get; }
|
|
IHistoryStore History { get; }
|
|
IHashStore Hashes { get; }
|
|
IFileRelationStore Relations { get; }
|
|
IRenameBatchStore RenameBatches { get; }
|
|
ISyncProfileStore SyncProfiles { get; }
|
|
IOperationProfileStore OperationProfiles { get; }
|
|
|
|
bool CanWrite { get; }
|
|
|
|
Task RunWriteAsync(Func<IIndexStore, Task> work, CancellationToken cancellationToken = default);
|
|
Task<T> RunWriteAsync<T>(Func<IIndexStore, Task<T>> work, CancellationToken cancellationToken = default);
|
|
}
|
|
|
|
public interface ISourceStore
|
|
{
|
|
Task<IReadOnlyList<Source>> GetAllAsync(CancellationToken cancellationToken = default);
|
|
Task<Source?> GetAsync(long id, CancellationToken cancellationToken = default);
|
|
Task<Source?> GetByStableKeyAsync(string key, CancellationToken cancellationToken = default);
|
|
Task<long> UpsertAsync(Source source, CancellationToken cancellationToken = default);
|
|
Task UpdateStatusAsync(long id, SourceStatus status, string? error, CancellationToken cancellationToken = default);
|
|
Task UpdateUsnAsync(long id, long journalId, long nextUsn, CancellationToken cancellationToken = default);
|
|
Task UpdateIndexedAsync(long id, DateTimeOffset utc, long generation, CancellationToken cancellationToken = default);
|
|
Task SetLastSeenAsync(long id, string rootPath, DateTimeOffset utc, CancellationToken cancellationToken = default);
|
|
Task DeleteAsync(long id, CancellationToken cancellationToken = default);
|
|
}
|
|
|
|
public interface IEntryStore
|
|
{
|
|
Task<IndexEntry?> GetAsync(long id, CancellationToken cancellationToken = default);
|
|
Task<IndexEntry?> GetRootAsync(long sourceId, CancellationToken cancellationToken = default);
|
|
Task<IndexEntry?> GetByPathAsync(long sourceId, string pathRel, CancellationToken cancellationToken = default);
|
|
Task<IndexEntry?> GetByParentNameAsync(long sourceId, long? parentId, string nameNorm, CancellationToken cancellationToken = default);
|
|
Task<IndexEntry?> GetByFileIdAsync(long sourceId, long fileId, CancellationToken cancellationToken = default);
|
|
Task<IReadOnlyList<IndexEntry>> GetChildrenAsync(long sourceId, long? parentId, EntryStatus? status = EntryStatus.Present, CancellationToken cancellationToken = default);
|
|
Task UpsertBatchAsync(IReadOnlyList<IndexEntry> entries, CancellationToken cancellationToken = default);
|
|
Task<long> UpsertAsync(IndexEntry entry, CancellationToken cancellationToken = default);
|
|
Task UpdateAggregatesAsync(long id, long aggregateSize, int files, int dirs, CancellationToken cancellationToken = default);
|
|
Task ApplySizeDeltaToAncestorsAsync(long? parentId, long sizeDelta, int fileDelta, int dirDelta, CancellationToken cancellationToken = default);
|
|
Task MarkMissingAsDeletedAsync(long sourceId, long generation, DateTimeOffset utc, string? pathRelPrefix, CancellationToken cancellationToken = default);
|
|
Task MarkSourceOfflineAsync(long sourceId, CancellationToken cancellationToken = default);
|
|
Task MarkSourceOnlinePresentAsync(long sourceId, CancellationToken cancellationToken = default);
|
|
Task TombstoneAsync(long id, DateTimeOffset utc, CancellationToken cancellationToken = default);
|
|
Task TombstoneByPathPrefixAsync(long sourceId, string pathRelPrefix, DateTimeOffset utc, CancellationToken cancellationToken = default);
|
|
Task DeleteExpiredTombstonesAsync(DateTimeOffset cutoffUtc, CancellationToken cancellationToken = default);
|
|
Task RenameSubtreePathAsync(long sourceId, string oldPathRel, string newPathRel, CancellationToken cancellationToken = default);
|
|
Task<long> CountPresentAsync(long sourceId, CancellationToken cancellationToken = default);
|
|
Task RefreshCategoryFromChildrenAsync(long folderOrArchiveId, CancellationToken cancellationToken = default);
|
|
Task SetUserCategoryAsync(long entryId, FileCategory category, string? reason = null, CancellationToken cancellationToken = default);
|
|
Task<int> BackfillCheapCategoriesAsync(int take, CancellationToken cancellationToken = default);
|
|
Task<IReadOnlyList<long>> GetArchiveIdsNeedingContentClassifyAsync(int take, CancellationToken cancellationToken = default);
|
|
Task<IReadOnlyList<IndexEntry>> GetUnknownFilesForSignatureAsync(int take, CancellationToken cancellationToken = default);
|
|
}
|
|
|
|
public interface IExcludeStore
|
|
{
|
|
Task<IReadOnlyList<ExcludeRule>> GetAllAsync(CancellationToken cancellationToken = default);
|
|
Task<long> AddAsync(ExcludeRule rule, CancellationToken cancellationToken = default);
|
|
Task RemoveAsync(long id, CancellationToken cancellationToken = default);
|
|
Task EnsureDefaultsAsync(IReadOnlyList<ExcludeRule> defaults, CancellationToken cancellationToken = default);
|
|
}
|
|
|
|
public interface IScanJobStore
|
|
{
|
|
Task<long> InsertAsync(ScanJob job, CancellationToken cancellationToken = default);
|
|
Task UpdateAsync(ScanJob job, CancellationToken cancellationToken = default);
|
|
Task InterruptRunningAsync(CancellationToken cancellationToken = default);
|
|
Task<bool> HasActiveAsync(long sourceId, CancellationToken cancellationToken = default);
|
|
Task AddErrorAsync(ScanError error, CancellationToken cancellationToken = default);
|
|
Task<ScanJob?> GetAsync(long id, CancellationToken cancellationToken = default);
|
|
Task<IReadOnlyList<ScanJob>> GetRecentAsync(int take, CancellationToken cancellationToken = default);
|
|
}
|
|
|
|
public interface ITransferStore
|
|
{
|
|
Task<long> InsertAsync(TransferJob job, CancellationToken cancellationToken = default);
|
|
Task UpdateAsync(TransferJob job, CancellationToken cancellationToken = default);
|
|
Task<IReadOnlyList<TransferJob>> GetIncompleteAsync(CancellationToken cancellationToken = default);
|
|
Task<IReadOnlyList<TransferJob>> GetHistoryAsync(int take, CancellationToken cancellationToken = default);
|
|
}
|
|
|
|
public interface ISearchStore
|
|
{
|
|
Task<IReadOnlyList<IndexEntry>> SearchAsync(SearchRequest request, CancellationToken cancellationToken = default);
|
|
}
|
|
|
|
public sealed class SearchRequest
|
|
{
|
|
public string? Name { get; init; }
|
|
public string? Extension { get; init; }
|
|
public bool? IsDirectory { get; init; }
|
|
public long? MinSize { get; init; }
|
|
public long? MaxSize { get; init; }
|
|
public DateTimeOffset? CreatedAfter { get; init; }
|
|
public DateTimeOffset? CreatedBefore { get; init; }
|
|
public DateTimeOffset? ModifiedAfter { get; init; }
|
|
public DateTimeOffset? ModifiedBefore { get; init; }
|
|
public IReadOnlyList<long>? SourceIds { get; init; }
|
|
public string? PathRelPrefix { get; init; }
|
|
public bool DirectChildrenOnly { get; init; }
|
|
public bool IncludeOffline { get; init; } = true;
|
|
public bool IncludeDeleted { get; init; }
|
|
public FileCategory? Category { get; init; }
|
|
public int Skip { get; init; }
|
|
public int Take { get; init; } = 500;
|
|
}
|
|
|
|
public interface IAnalysisStore
|
|
{
|
|
Task EnsureReadyAsync(CancellationToken cancellationToken = default);
|
|
Task<long> GetIndexStampAsync(CancellationToken cancellationToken = default);
|
|
Task<IReadOnlyList<IndexEntry>> GetDirectoryRootsAsync(CancellationToken cancellationToken = default);
|
|
Task<IReadOnlyList<IndexEntry>> LargestDirectoriesAsync(long? sourceId, long? parentId, int take, CancellationToken cancellationToken = default);
|
|
Task<IReadOnlyList<IndexEntry>> LargestFilesAsync(long? sourceId, string? pathRelPrefix, int take, CancellationToken cancellationToken = default);
|
|
Task<IReadOnlyList<ExtensionUsage>> UsageByExtensionAsync(long? sourceId, string? pathRelPrefix, int take, CancellationToken cancellationToken = default);
|
|
Task<IReadOnlyList<CategoryUsage>> UsageByCategoryAsync(long? sourceId, string? pathRelPrefix, int take, CancellationToken cancellationToken = default);
|
|
Task<IReadOnlyList<SourceUsage>> UsageBySourceAsync(CancellationToken cancellationToken = default);
|
|
Task<IReadOnlyList<IndexEntry>> ChildrenBySizeAsync(long parentId, int take, CancellationToken cancellationToken = default);
|
|
}
|
|
|
|
public sealed class ExtensionUsage
|
|
{
|
|
public required string Extension { get; init; }
|
|
public long TotalSize { get; init; }
|
|
public long FileCount { get; init; }
|
|
}
|
|
|
|
public sealed class CategoryUsage
|
|
{
|
|
public required string Category { get; init; }
|
|
public long TotalSize { get; init; }
|
|
public long FileCount { get; init; }
|
|
}
|
|
|
|
public sealed class SourceUsage
|
|
{
|
|
public long SourceId { get; init; }
|
|
public required string DisplayName { get; init; }
|
|
public long TotalSize { get; init; }
|
|
public long FileCount { get; init; }
|
|
public SourceStatus Status { get; init; }
|
|
}
|
|
|
|
public interface IHistoryStore
|
|
{
|
|
Task CaptureSourceSnapshotAsync(long sourceId, DateTimeOffset utc, CancellationToken cancellationToken = default);
|
|
Task CaptureDirectorySnapshotsAsync(long sourceId, DateTimeOffset utc, long minSize, int topN, CancellationToken cancellationToken = default);
|
|
Task<IReadOnlyList<SourceSnapshot>> GetSourceHistoryAsync(long sourceId, CancellationToken cancellationToken = default);
|
|
}
|
|
|
|
public sealed class SourceSnapshot
|
|
{
|
|
public DateTimeOffset CapturedUtc { get; init; }
|
|
public long TotalSize { get; init; }
|
|
public long FileCount { get; init; }
|
|
public long DirCount { get; init; }
|
|
}
|
|
|
|
public interface IHashStore
|
|
{
|
|
Task EnqueueSizeCollisionsAsync(long? sourceId, CancellationToken cancellationToken = default);
|
|
Task<bool> HasPendingAsync(CancellationToken cancellationToken = default);
|
|
Task<long> CountPendingAsync(CancellationToken cancellationToken = default);
|
|
Task<IReadOnlyList<HashWorkItem>> DequeueAsync(int take, CancellationToken cancellationToken = default);
|
|
Task CompletePartialAsync(long entryId, byte[] hash, CancellationToken cancellationToken = default);
|
|
Task CompleteFullAsync(long entryId, byte[] hash, CancellationToken cancellationToken = default);
|
|
Task MarkUniquePartialAsync(long entryId, CancellationToken cancellationToken = default);
|
|
Task MarkErrorAsync(long entryId, CancellationToken cancellationToken = default);
|
|
Task MarkSkippedAsync(long entryId, CancellationToken cancellationToken = default);
|
|
Task<bool> HasPartialCollisionAsync(long entryId, long sizeBytes, CancellationToken cancellationToken = default);
|
|
Task<IReadOnlyList<DuplicateGroup>> GetDuplicateGroupsAsync(long? sourceId, string? pathPrefix, int take, CancellationToken cancellationToken = default);
|
|
Task<IReadOnlyList<byte[]>> GetDuplicateHashesAsync(long? sourceId, string? pathPrefix, int take, CancellationToken cancellationToken = default);
|
|
Task<IReadOnlyList<DuplicateGroup>> GetDuplicateGroupsByHashesAsync(
|
|
IReadOnlyList<byte[]> hashes,
|
|
CancellationToken cancellationToken = default);
|
|
}
|
|
|
|
public interface IFileRelationStore
|
|
{
|
|
Task<IReadOnlyList<FileRelation>> GetAmongAsync(IReadOnlyList<long> entryIds, CancellationToken cancellationToken = default);
|
|
Task UpsertAsync(FileRelation relation, CancellationToken cancellationToken = default);
|
|
Task DeleteAmongAsync(IReadOnlyList<long> entryIds, IReadOnlyList<FileRelationKind> kinds, CancellationToken cancellationToken = default);
|
|
}
|
|
|
|
public interface IRenameBatchStore
|
|
{
|
|
Task<long> CreateAsync(IReadOnlyList<RenameBatchItem> items, CancellationToken cancellationToken = default);
|
|
Task<RenameBatch?> GetLatestUndoableAsync(CancellationToken cancellationToken = default);
|
|
Task MarkUndoneAsync(long id, CancellationToken cancellationToken = default);
|
|
}
|
|
|
|
public interface ISyncProfileStore
|
|
{
|
|
Task<IReadOnlyList<SyncProfile>> ListAsync(CancellationToken cancellationToken = default);
|
|
Task<SyncProfile?> GetAsync(long id, CancellationToken cancellationToken = default);
|
|
Task<long> UpsertAsync(SyncProfile profile, CancellationToken cancellationToken = default);
|
|
Task DeleteAsync(long id, CancellationToken cancellationToken = default);
|
|
}
|
|
|
|
public interface IOperationProfileStore
|
|
{
|
|
Task<IReadOnlyList<OperationProfile>> ListAsync(CancellationToken cancellationToken = default);
|
|
Task<OperationProfile?> GetAsync(long id, CancellationToken cancellationToken = default);
|
|
Task<long> UpsertAsync(OperationProfile profile, CancellationToken cancellationToken = default);
|
|
Task DeleteAsync(long id, CancellationToken cancellationToken = default);
|
|
}
|
|
|
|
public sealed class HashWorkItem
|
|
{
|
|
public long EntryId { get; init; }
|
|
public long SizeBytes { get; init; }
|
|
public required string State { get; init; }
|
|
public long SourceId { get; init; }
|
|
public required string PathRel { get; init; }
|
|
public string? RootPath { get; init; }
|
|
public long? FileId { get; init; }
|
|
public int Attributes { get; init; }
|
|
public CloudAvailability? CloudAvailability { get; init; }
|
|
}
|
|
|
|
public sealed class DuplicateGroup
|
|
{
|
|
public long SizeBytes { get; init; }
|
|
public byte[]? Hash { get; init; }
|
|
public IReadOnlyList<IndexEntry> Entries { get; init; } = [];
|
|
public bool SameFileId { get; init; }
|
|
}
|