2017-04-17 13:37:52 +08:00
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System ;
2017-10-23 16:56:04 +08:00
using System.Threading ;
2017-04-17 13:37:52 +08:00
using osu.Framework.Logging ;
2017-07-26 19:22:02 +08:00
using osu.Framework.Platform ;
2017-04-17 13:37:52 +08:00
namespace osu.Game.Database
{
2017-07-27 15:56:41 +08:00
public abstract class DatabaseBackedStore
2017-04-17 13:37:52 +08:00
{
2017-07-26 19:22:02 +08:00
protected readonly Storage Storage ;
2017-04-17 13:37:52 +08:00
2017-10-23 15:35:35 +08:00
/// <summary>
/// Create a new <see cref="OsuDbContext"/> instance (separate from the shared context via <see cref="GetContext"/> for performing isolated operations.
/// </summary>
protected readonly Func < OsuDbContext > CreateContext ;
2017-10-17 14:00:27 +08:00
2017-10-23 16:56:04 +08:00
private readonly ThreadLocal < OsuDbContext > queryContext ;
2017-10-23 15:35:35 +08:00
/// <summary>
/// Retrieve a shared context for performing lookups (or write operations on the update thread, for now).
/// </summary>
protected OsuDbContext GetContext ( ) = > queryContext . Value ;
protected DatabaseBackedStore ( Func < OsuDbContext > createContext , Storage storage = null )
2017-04-17 13:37:52 +08:00
{
2017-10-23 15:35:35 +08:00
CreateContext = createContext ;
2017-10-23 16:56:04 +08:00
// todo: while this seems to work quite well, we need to consider that contexts could enter a state where they are never cleaned up.
queryContext = new ThreadLocal < OsuDbContext > ( CreateContext ) ;
2017-10-23 15:35:35 +08:00
2017-07-26 19:22:02 +08:00
Storage = storage ;
2017-04-17 13:37:52 +08:00
try
{
Prepare ( ) ;
}
catch ( Exception e )
{
2017-04-17 16:43:48 +08:00
Logger . Error ( e , $@"Failed to initialise the {GetType()}! Trying again with a clean database..." ) ;
2017-04-17 18:44:03 +08:00
Prepare ( true ) ;
2017-04-17 13:37:52 +08:00
}
}
/// <summary>
2017-10-17 18:58:33 +08:00
/// Perform any common clean-up tasks. Should be run when idle, or whenever necessary.
2017-08-01 09:08:05 +08:00
/// </summary>
2017-10-17 18:58:33 +08:00
public virtual void Cleanup ( )
2017-08-01 09:08:05 +08:00
{
}
/// <summary>
/// Prepare this database for use. Tables should be created here.
2017-04-17 13:37:52 +08:00
/// </summary>
2017-04-17 18:44:03 +08:00
protected abstract void Prepare ( bool reset = false ) ;
2017-04-17 13:37:52 +08:00
/// <summary>
/// Reset this database to a default state. Undo all changes to database and storage backings.
/// </summary>
2017-04-17 18:44:03 +08:00
public void Reset ( ) = > Prepare ( true ) ;
2017-04-17 13:37:52 +08:00
}
2017-07-27 14:06:10 +08:00
}