mirror of https://github.com/Squidex/squidex.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
125 lines
3.8 KiB
125 lines
3.8 KiB
// ==========================================================================
|
|
// Squidex Headless CMS
|
|
// ==========================================================================
|
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|
// All rights reserved. Licensed under the MIT license.
|
|
// ==========================================================================
|
|
|
|
using System;
|
|
using System.IO;
|
|
using System.IO.Compression;
|
|
using System.Threading.Tasks;
|
|
using Squidex.Domain.Apps.Entities.Backup.Helpers;
|
|
using Squidex.Domain.Apps.Entities.Backup.Model;
|
|
using Squidex.Infrastructure;
|
|
using Squidex.Infrastructure.EventSourcing;
|
|
using Squidex.Infrastructure.Json;
|
|
using Squidex.Infrastructure.States;
|
|
|
|
#pragma warning disable SA1401 // Fields must be private
|
|
|
|
namespace Squidex.Domain.Apps.Entities.Backup
|
|
{
|
|
public class BackupReader : DisposableObjectBase, IBackupReader
|
|
{
|
|
private readonly ZipArchive archive;
|
|
private readonly IJsonSerializer serializer;
|
|
private int readEvents;
|
|
private int readAttachments;
|
|
|
|
public int ReadEvents
|
|
{
|
|
get { return readEvents; }
|
|
}
|
|
|
|
public int ReadAttachments
|
|
{
|
|
get { return readAttachments; }
|
|
}
|
|
|
|
public BackupReader(IJsonSerializer serializer, Stream stream)
|
|
{
|
|
Guard.NotNull(serializer, nameof(serializer));
|
|
|
|
this.serializer = serializer;
|
|
|
|
archive = new ZipArchive(stream, ZipArchiveMode.Read, false);
|
|
}
|
|
|
|
protected override void DisposeObject(bool disposing)
|
|
{
|
|
if (disposing)
|
|
{
|
|
archive.Dispose();
|
|
}
|
|
}
|
|
|
|
public Task<T> ReadJsonAsync<T>(string name)
|
|
{
|
|
Guard.NotNullOrEmpty(name, nameof(name));
|
|
|
|
var entry = GetEntry(name);
|
|
|
|
using (var stream = entry.Open())
|
|
{
|
|
return Task.FromResult(serializer.Deserialize<T>(stream, null));
|
|
}
|
|
}
|
|
|
|
public async Task ReadBlobAsync(string name, Func<Stream, Task> handler)
|
|
{
|
|
Guard.NotNullOrEmpty(name, nameof(name));
|
|
Guard.NotNull(handler, nameof(handler));
|
|
|
|
var entry = GetEntry(name);
|
|
|
|
using (var stream = entry.Open())
|
|
{
|
|
await handler(stream);
|
|
}
|
|
}
|
|
|
|
private ZipArchiveEntry GetEntry(string name)
|
|
{
|
|
var attachmentEntry = archive.GetEntry(ArchiveHelper.GetAttachmentPath(name));
|
|
|
|
if (attachmentEntry == null || attachmentEntry.Length == 0)
|
|
{
|
|
throw new FileNotFoundException("Cannot find attachment.", name);
|
|
}
|
|
|
|
readAttachments++;
|
|
|
|
return attachmentEntry;
|
|
}
|
|
|
|
public async Task ReadEventsAsync(IStreamNameResolver streamNameResolver, IEventDataFormatter formatter, Func<(string Stream, Envelope<IEvent> Event), Task> handler)
|
|
{
|
|
Guard.NotNull(handler, nameof(handler));
|
|
Guard.NotNull(formatter, nameof(formatter));
|
|
Guard.NotNull(streamNameResolver, nameof(streamNameResolver));
|
|
|
|
while (true)
|
|
{
|
|
var eventEntry = archive.GetEntry(ArchiveHelper.GetEventPath(readEvents));
|
|
|
|
if (eventEntry == null)
|
|
{
|
|
break;
|
|
}
|
|
|
|
using (var stream = eventEntry.Open())
|
|
{
|
|
var storedEvent = serializer.Deserialize<CompatibleStoredEvent>(stream).ToStoredEvent();
|
|
|
|
var eventStream = storedEvent.StreamName;
|
|
var eventEnvelope = formatter.Parse(storedEvent);
|
|
|
|
await handler((eventStream, eventEnvelope));
|
|
}
|
|
|
|
readEvents++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|