using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using Duplicati.Library.Interface; namespace Duplicati.Library.Main.Backend; #nullable enable partial class BackendManager { /// /// Represents a pending LIST operation /// /// /// Creates a new ListOperation /// /// The execution context /// The cancellation token private class ListOperation(ExecuteContext context, CancellationToken cancelToken) : PendingOperation>(context, true, cancelToken) { /// /// The operation type /// public override BackendActionType Operation => BackendActionType.List; /// /// Executes the operation /// /// The backend to list /// The cancellation token /// An awaitable task public override async Task> ExecuteAsync(IBackend backend, CancellationToken cancelToken) { Context.Statwriter.SendEvent(BackendActionType.List, BackendEventType.Started, null, -1); // TODO: Consider returning IAsyncEnumerable instead of List var r = await backend.ListAsync(cancelToken).ToListAsync(cancelToken).ConfigureAwait(false); // TODO: Investigate better way to solve this so we do not use memory for large lists var sb = new StringBuilder(); sb.AppendLine("["); long count = 0; foreach (var e in r) { if (count != 0) sb.AppendLine(","); count++; sb.Append(System.Text.Json.JsonSerializer.Serialize(e)); } sb.AppendLine(); sb.Append("]"); Context.Database.LogRemoteOperation("list", "", sb.ToString()); Context.Statwriter.SendEvent(BackendActionType.List, BackendEventType.Completed, null, r.Count); return r; } } }