2018-01-05 19:21:19 +08:00
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
2017-04-17 13:37:52 +08:00
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
2017-10-25 21:07:32 +08:00
using System.Linq ;
using Microsoft.EntityFrameworkCore ;
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>
2018-02-12 22:10:05 +08:00
protected readonly IDatabaseContextFactory ContextFactory ;
2017-10-23 15:35:35 +08:00
2017-10-25 17:28:28 +08:00
/// <summary>
2017-10-25 21:07:32 +08:00
/// Refresh an instance potentially from a different thread with a local context-tracked instance.
2017-10-25 17:28:28 +08:00
/// </summary>
2017-10-25 21:19:47 +08:00
/// <param name="obj">The object to use as a reference when negotiating a local instance.</param>
/// <param name="lookupSource">An optional lookup source which will be used to query and populate a freshly retrieved replacement. If not provided, the refreshed object will still be returned but will not have any includes.</param>
/// <typeparam name="T">A valid EF-stored type.</typeparam>
2018-02-15 14:51:59 +08:00
protected virtual void Refresh < T > ( ref T obj , IQueryable < T > lookupSource = null ) where T : class , IHasPrimaryKey
2017-10-25 21:07:32 +08:00
{
2018-02-12 16:55:11 +08:00
using ( var usage = ContextFactory . GetForWrite ( ) )
2018-01-24 16:35:37 +08:00
{
2018-02-12 16:55:11 +08:00
var context = usage . Context ;
if ( context . Entry ( obj ) . State ! = EntityState . Detached ) return ;
var id = obj . ID ;
var foundObject = lookupSource ? . SingleOrDefault ( t = > t . ID = = id ) ? ? context . Find < T > ( id ) ;
if ( foundObject ! = null )
obj = foundObject ;
else
context . Add ( obj ) ;
2018-01-24 16:35:37 +08:00
}
2017-10-25 21:07:32 +08:00
}
2017-10-25 17:28:28 +08:00
2018-02-12 22:10:05 +08:00
protected DatabaseBackedStore ( IDatabaseContextFactory contextFactory , Storage storage = null )
2017-04-17 13:37:52 +08:00
{
2018-02-12 16:55:11 +08:00
ContextFactory = contextFactory ;
2017-07-26 19:22:02 +08:00
Storage = storage ;
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>
2018-02-15 12:30:17 +08:00
public virtual void PurgeDeletable ( )
2017-08-01 09:08:05 +08:00
{
}
2017-04-17 13:37:52 +08:00
}
2017-07-27 14:06:10 +08:00
}