Add the ability to create migrations on a per-store level

Now stores store versions to the database itself.
This commit is contained in:
Dean Herbert 2017-07-27 20:38:35 +09:00
parent cb68f18f47
commit 3a6f3cdd8a
5 changed files with 76 additions and 0 deletions

View File

@ -17,6 +17,12 @@ public class BeatmapStore : DatabaseBackedStore
public event Action<BeatmapSetInfo> BeatmapSetAdded;
public event Action<BeatmapSetInfo> BeatmapSetRemoved;
/// <summary>
/// The current version of this store. Used for migrations (see <see cref="PerformMigration(int, int)"/>).
/// The initial version is 1.
/// </summary>
protected override int StoreVersion => 1;
public BeatmapStore(SQLiteConnection connection)
: base(connection)
{
@ -50,6 +56,33 @@ protected override void Prepare(bool reset = false)
cleanupPendingDeletions();
}
/// <summary>
/// Perform migrations between two store versions.
/// </summary>
/// <param name="currentVersion">The current store version. This will be zero on a fresh database initialisation.</param>
/// <param name="newVersion">The target version which we are migrating to (equal to the current <see cref="StoreVersion"/>).</param>
protected override void PerformMigration(int currentVersion, int newVersion)
{
base.PerformMigration(currentVersion, newVersion);
while (currentVersion++ < newVersion)
{
switch (currentVersion)
{
case 1:
// initialising from a version before we had versioning (or a fresh install).
// force adding of Protected column (not automatically migrated).
Connection.MigrateTable<BeatmapSetInfo>();
// remove all existing beatmaps.
foreach (var b in Connection.GetAllWithChildren<BeatmapSetInfo>(null, true))
Connection.Delete(b, true);
break;
}
}
}
/// <summary>
/// Add a <see cref="BeatmapSetInfo"/> to the database.
/// </summary>

View File

@ -17,6 +17,8 @@ public abstract class DatabaseBackedStore
protected readonly Storage Storage;
protected readonly SQLiteConnection Connection;
protected virtual int StoreVersion => 1;
protected DatabaseBackedStore(SQLiteConnection connection, Storage storage = null)
{
Storage = storage;
@ -31,6 +33,28 @@ protected DatabaseBackedStore(SQLiteConnection connection, Storage storage = nul
Logger.Error(e, $@"Failed to initialise the {GetType()}! Trying again with a clean database...");
Prepare(true);
}
checkMigrations();
}
private void checkMigrations()
{
var storeName = GetType().Name;
var reportedVersion = Connection.Table<StoreVersion>().FirstOrDefault(s => s.StoreName == storeName) ?? new StoreVersion
{
StoreName = storeName,
Version = 0
};
if (reportedVersion.Version != StoreVersion)
PerformMigration(reportedVersion.Version, reportedVersion.Version = StoreVersion);
Connection.InsertOrReplace(reportedVersion);
}
protected virtual void PerformMigration(int currentVersion, int newVersion)
{
}
/// <summary>

View File

@ -0,0 +1,15 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using SQLite.Net.Attributes;
namespace osu.Game.Database
{
public class StoreVersion
{
[PrimaryKey]
public string StoreName { get; set; }
public int Version { get; set; }
}
}

View File

@ -18,6 +18,7 @@
using osu.Game.Online.API;
using SQLite.Net;
using osu.Framework.Graphics.Performance;
using osu.Game.Database;
using osu.Game.IO;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Scoring;
@ -97,6 +98,8 @@ private void load()
SQLiteConnection connection = Host.Storage.GetDatabase(@"client");
connection.CreateTable<StoreVersion>();
dependencies.Cache(RulesetStore = new RulesetStore(connection));
dependencies.Cache(FileStore = new FileStore(connection, Host.Storage));
dependencies.Cache(BeatmapManager = new BeatmapManager(Host.Storage, FileStore, connection, RulesetStore, Host));

View File

@ -80,6 +80,7 @@
<Compile Include="Beatmaps\DifficultyCalculator.cs" />
<Compile Include="Beatmaps\DummyWorkingBeatmap.cs" />
<Compile Include="Beatmaps\IO\LegacyFilesystemReader.cs" />
<Compile Include="Database\StoreVersion.cs" />
<Compile Include="Graphics\Containers\OsuClickableContainer.cs" />
<Compile Include="Graphics\Containers\OsuFocusedOverlayContainer.cs" />
<Compile Include="Graphics\Containers\OsuScrollContainer.cs" />