…lines 1–293 unchanged (293 lines)
294
295 ICollection<(Type Type, Func<IAsyncEnumerable<object>> ValueFactory)> entityTypes = [
296 .. typeof(JellyfinDbContext)
297 .GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance)
298 .Where(e => e.PropertyType.IsAssignableTo(typeof(IQueryable)))
299 .Select(e => (Type: e.PropertyType, ValueFactory: new Func<IAsyncEnumerable<object>>(() => GetValues((IQueryable)e.GetValue(dbContext)!, e.PropertyType)))),
300 (Type: typeof(IQueryable<HistoryRow>), ValueFactory: new Func<IAsyncEnumerable<object>>(() => migrations.ToAsyncEnumerable()))
301 ];
302 manifest.DatabaseTables = entityTypes.Select(e => e.Type.Name).ToArray();
303 var transaction = await dbContext.Database.BeginTransactionAsync().ConfigureAwait(false);
304
305 await using (transaction.ConfigureAwait(false))
306 {
307 _logger.LogInformation("Begin Database backup");
308
309 foreach (var entityType in entityTypes)
310 {
311 var schemaName = dbContext.Model.FindEntityType(entityType.Type.GetGenericArguments()[0])!.GetSchemaQualifiedTableName()!;
312 _logger.LogInformation("Begin backup of entity {Table}", entityType.Type.Name);
313 var zipEntry = zipArchive.CreateEntry($"Database\\{entityType.Type.Name}.json");
314 var entities = 0;
315 var zipEntryStream = zipEntry.Open();
316 await using (zipEntryStream.ConfigureAwait(false))
317 {
…lines 318–514 unchanged (197 lines)