diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs
index 78042349d1..4ff16b604a 100644
--- a/osu.Game/Beatmaps/BeatmapManager.cs
+++ b/osu.Game/Beatmaps/BeatmapManager.cs
@@ -91,7 +91,8 @@ namespace osu.Game.Beatmaps
protected override void Populate(BeatmapSetInfo model, ArchiveReader archive)
{
- model.Beatmaps = createBeatmapDifficulties(archive);
+ if (archive != null)
+ model.Beatmaps = createBeatmapDifficulties(archive);
foreach (BeatmapInfo b in model.Beatmaps)
{
diff --git a/osu.Game/Database/ArchiveModelManager.cs b/osu.Game/Database/ArchiveModelManager.cs
index cbf0df3227..0465c0ad73 100644
--- a/osu.Game/Database/ArchiveModelManager.cs
+++ b/osu.Game/Database/ArchiveModelManager.cs
@@ -5,6 +5,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
+using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore;
using osu.Framework.IO.File;
using osu.Framework.Logging;
@@ -175,7 +176,24 @@ namespace osu.Game.Database
/// The archive to be imported.
public TModel Import(ArchiveReader archive)
{
- TModel item = null;
+ try
+ {
+ return Import(CreateModel(archive), archive);
+ }
+ catch (Exception e)
+ {
+ Logger.Error(e, $"Model creation of {archive.Name} failed.", LoggingTarget.Database);
+ return null;
+ }
+ }
+
+ ///
+ /// Import an item from a .
+ ///
+ /// The model to be imported.
+ /// An optional archive to use for model population.
+ public TModel Import(TModel item, ArchiveReader archive = null)
+ {
delayEvents();
try
@@ -186,18 +204,16 @@ namespace osu.Game.Database
{
if (!write.IsTransactionLeader) throw new InvalidOperationException($"Ensure there is no parent transaction so errors can correctly be handled by {this}");
- // create a new model (don't yet add to database)
- item = CreateModel(archive);
-
var existing = CheckForExisting(item);
if (existing != null)
{
- Logger.Log($"Found existing {typeof(TModel)} for {archive.Name} (ID {existing.ID}). Skipping import.", LoggingTarget.Database);
+ Logger.Log($"Found existing {typeof(TModel)} for {item} (ID {existing.ID}). Skipping import.", LoggingTarget.Database);
return existing;
}
- item.Files = createFileInfos(archive, Files);
+ if (archive != null)
+ item.Files = createFileInfos(archive, Files);
Populate(item, archive);
@@ -211,11 +227,11 @@ namespace osu.Game.Database
}
}
- Logger.Log($"Import of {archive.Name} successfully completed!", LoggingTarget.Database);
+ Logger.Log($"Import of {item} successfully completed!", LoggingTarget.Database);
}
catch (Exception e)
{
- Logger.Error(e, $"Import of {archive.Name} failed and has been rolled back.", LoggingTarget.Database);
+ Logger.Error(e, $"Import of {item} failed and has been rolled back.", LoggingTarget.Database);
item = null;
}
finally
@@ -227,12 +243,6 @@ namespace osu.Game.Database
return item;
}
- ///
- /// Import an item from a .
- ///
- /// The model to be imported.
- public void Import(TModel item) => ModelStore.Add(item);
-
///
/// Perform an update of the specified item.
/// TODO: Support file changes.
@@ -385,8 +395,8 @@ namespace osu.Game.Database
/// After this method, the model should be in a state ready to commit to a store.
///
/// The model to populate.
- /// The archive to use as a reference for population.
- protected virtual void Populate(TModel model, ArchiveReader archive)
+ /// The archive to use as a reference for population. May be null.
+ protected virtual void Populate(TModel model, [CanBeNull] ArchiveReader archive)
{
}
diff --git a/osu.Game/Database/SingletonContextFactory.cs b/osu.Game/Database/SingletonContextFactory.cs
index ce3fbf6881..a7158c0583 100644
--- a/osu.Game/Database/SingletonContextFactory.cs
+++ b/osu.Game/Database/SingletonContextFactory.cs
@@ -14,6 +14,6 @@ namespace osu.Game.Database
public OsuDbContext Get() => context;
- public DatabaseWriteUsage GetForWrite(bool withTransaction = true) => new DatabaseWriteUsage(context, null);
+ public DatabaseWriteUsage GetForWrite(bool withTransaction = true) => new DatabaseWriteUsage(context, null) { IsTransactionLeader = true };
}
}